diff --git a/configs/gunicorn_config.py b/configs/gunicorn_config.py index b7578015..d7279d3e 100644 --- a/configs/gunicorn_config.py +++ b/configs/gunicorn_config.py @@ -19,6 +19,7 @@ from gunicorn.glogging import Logger def get_workers(): import multiprocessing + return multiprocessing.cpu_count() * 2 + 1 @@ -26,10 +27,10 @@ bind = "127.0.0.1:10020" # Error logging output for gunicorn (-) is stdout -errorlog = '-' +errorlog = "-" # Access logging output for gunicorn (-) is stdout -accesslog = '-' +accesslog = "-" # SERVER MECHANICS @@ -42,45 +43,45 @@ tmp_upload_dir = None reuse_port = True # Custom log format -#access_log_format = ( +# access_log_format = ( # '%(t)s %(p)s INFO [GNCRN] %(h)-15s rqt:%(L)s %(s)s %(b)-6s "%(m)s:%(U)s %(q)s" usr:%(u)s "%(f)s" "%(a)s"') # loki format for easier parsing in grafana -loki_access_log_format = ( - 'time="%(t)s" pid=%(p)s level="INFO" type="[GNCRN]" ip="%(h)-15s" rqt="%(L)s" response_code="%(s)s" response_bytes="%(b)-6s" uri="%(m)s:%(U)s %(q)s" user=":%(u)s" user_agent="%(a)s"') +loki_access_log_format = 'time="%(t)s" pid=%(p)s level="INFO" type="[GNCRN]" ip="%(h)-15s" rqt="%(L)s" response_code="%(s)s" response_bytes="%(b)-6s" uri="%(m)s:%(U)s %(q)s" user=":%(u)s" user_agent="%(a)s"' # JSON format -json_access_log_format = json.dumps({ - 'time': r'%(t)s', - 'pid': r'%(p)s', - 'level': 'INFO', - 'ip': r'%(h)s', - 'request_time': r'%(L)s', - 'remote_address': r'%(h)s', - 'user_name': r'%(u)s', - 'status': r'%(s)s', - 'method': r'%(m)s', - 'url_path': r'%(U)s', - 'query_string': r'%(q)s', - 'protocol': r'%(H)s', - 'response_length': r'%(B)s', - 'referer': r'%(f)s', - 'user_agent': r'%(a)s', - -}) +json_access_log_format = json.dumps( + { + "time": r"%(t)s", + "pid": r"%(p)s", + "level": "INFO", + "ip": r"%(h)s", + "request_time": r"%(L)s", + "remote_address": r"%(h)s", + "user_name": r"%(u)s", + "status": r"%(s)s", + "method": r"%(m)s", + "url_path": r"%(U)s", + "query_string": r"%(q)s", + "protocol": r"%(H)s", + "response_length": r"%(B)s", + "referer": r"%(f)s", + "user_agent": r"%(a)s", + } +) access_log_format = loki_access_log_format -if os.environ.get('RC_LOGGING_FORMATTER') == 'json': +if os.environ.get("RC_LOGGING_FORMATTER") == "json": access_log_format = json_access_log_format # self adjust workers based on CPU count, to use maximum of CPU and not overquota the resources # workers = get_workers() # Gunicorn access log level -loglevel = 'info' +loglevel = "info" # Process name visible in a process list -proc_name = 'rhodecode_enterprise' +proc_name = "rhodecode_enterprise" # Type of worker class, one of `sync`, `gevent` or `gthread` # currently `sync` is the only option allowed for vcsserver and for rhodecode all of 3 are allowed @@ -90,7 +91,7 @@ proc_name = 'rhodecode_enterprise' # gthread: # In this case, the maximum number of concurrent requests is (N workers * X threads) # e.g. workers = 3 threads=3 = 3*3, 9 concurrent requests can be handled -worker_class = 'gthread' +worker_class = "gthread" # Sets the number of process workers. More workers means more concurrent connections # RhodeCode can handle at the same time. Each additional worker also it increases @@ -173,6 +174,7 @@ class MemoryCheckConfig: def _get_process_rss(pid=None): try: import psutil + if pid: proc = psutil.Process(pid) else: @@ -203,30 +205,30 @@ def get_memory_usage_params(config=None): ini_path = os.path.abspath(config) conf = _get_config(ini_path) - section = 'server:main' + section = "server:main" if conf and conf.has_section(section): + if conf.has_option(section, "memory_max_usage"): + _memory_max_usage = conf.getint(section, "memory_max_usage") - if conf.has_option(section, 'memory_max_usage'): - _memory_max_usage = conf.getint(section, 'memory_max_usage') + if conf.has_option(section, "memory_usage_check_interval"): + _memory_usage_check_interval = conf.getint(section, "memory_usage_check_interval") - if conf.has_option(section, 'memory_usage_check_interval'): - _memory_usage_check_interval = conf.getint(section, 'memory_usage_check_interval') + if conf.has_option(section, "memory_usage_recovery_threshold"): + _memory_usage_recovery_threshold = conf.getfloat(section, "memory_usage_recovery_threshold") - if conf.has_option(section, 'memory_usage_recovery_threshold'): - _memory_usage_recovery_threshold = conf.getfloat(section, 'memory_usage_recovery_threshold') - - _memory_max_usage = int(os.environ.get('RC_GUNICORN_MEMORY_MAX_USAGE', '') - or _memory_max_usage) - _memory_usage_check_interval = int(os.environ.get('RC_GUNICORN_MEMORY_USAGE_CHECK_INTERVAL', '') - or _memory_usage_check_interval) - _memory_usage_recovery_threshold = float(os.environ.get('RC_GUNICORN_MEMORY_USAGE_RECOVERY_THRESHOLD', '') - or _memory_usage_recovery_threshold) + _memory_max_usage = int(os.environ.get("RC_GUNICORN_MEMORY_MAX_USAGE", "") or _memory_max_usage) + _memory_usage_check_interval = int( + os.environ.get("RC_GUNICORN_MEMORY_USAGE_CHECK_INTERVAL", "") or _memory_usage_check_interval + ) + _memory_usage_recovery_threshold = float( + os.environ.get("RC_GUNICORN_MEMORY_USAGE_RECOVERY_THRESHOLD", "") or _memory_usage_recovery_threshold + ) return MemoryCheckConfig(_memory_max_usage, _memory_usage_check_interval, _memory_usage_recovery_threshold) def _time_with_offset(check_interval): - return time.time() - random.randint(0, check_interval/2.0) + return time.time() - random.randint(0, check_interval / 2.0) def pre_fork(server, worker): @@ -234,26 +236,27 @@ def pre_fork(server, worker): def post_fork(server, worker): - memory_conf = get_memory_usage_params() _memory_max_usage = memory_conf.max_usage _memory_usage_check_interval = memory_conf.check_interval _memory_usage_recovery_threshold = memory_conf.recovery_threshold - worker._memory_max_usage = int(os.environ.get('RC_GUNICORN_MEMORY_MAX_USAGE', '') - or _memory_max_usage) - worker._memory_usage_check_interval = int(os.environ.get('RC_GUNICORN_MEMORY_USAGE_CHECK_INTERVAL', '') - or _memory_usage_check_interval) - worker._memory_usage_recovery_threshold = float(os.environ.get('RC_GUNICORN_MEMORY_USAGE_RECOVERY_THRESHOLD', '') - or _memory_usage_recovery_threshold) + worker._memory_max_usage = int(os.environ.get("RC_GUNICORN_MEMORY_MAX_USAGE", "") or _memory_max_usage) + worker._memory_usage_check_interval = int( + os.environ.get("RC_GUNICORN_MEMORY_USAGE_CHECK_INTERVAL", "") or _memory_usage_check_interval + ) + worker._memory_usage_recovery_threshold = float( + os.environ.get("RC_GUNICORN_MEMORY_USAGE_RECOVERY_THRESHOLD", "") or _memory_usage_recovery_threshold + ) # register memory last check time, with some random offset so we don't recycle all # at once worker._last_memory_check_time = _time_with_offset(_memory_usage_check_interval) if _memory_max_usage: - server.log.info("pid=[%-10s] WORKER spawned with max memory set at %s", worker.pid, - _format_data_size(_memory_max_usage)) + server.log.info( + "pid=[%-10s] WORKER spawned with max memory set at %s", worker.pid, _format_data_size(_memory_max_usage) + ) else: server.log.info("pid=[%-10s] WORKER spawned", worker.pid) @@ -263,9 +266,9 @@ def pre_exec(server): def on_starting(server): - server_lbl = '{} {}'.format(server.proc_name, server.address) + server_lbl = "{} {}".format(server.proc_name, server.address) server.log.info("Server %s is starting.", server_lbl) - server.log.info('Config:') + server.log.info("Config:") server.log.info(f"\n{server.cfg}") server.log.info(get_memory_usage_params()) @@ -299,10 +302,10 @@ def _format_data_size(size, unit="B", precision=1, binary=True): if not binary: base = 1000 - multiples = ('', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y') + multiples = ("", "k", "M", "G", "T", "P", "E", "Z", "Y") else: base = 1024 - multiples = ('', 'Ki', 'Mi', 'Gi', 'Ti', 'Pi', 'Ei', 'Zi', 'Yi') + multiples = ("", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei", "Zi", "Yi") sign = "" if size > 0: @@ -317,13 +320,13 @@ def _format_data_size(size, unit="B", precision=1, binary=True): m = 8 if m == 0: - precision = '%.0f' + precision = "%.0f" else: - precision = '%%.%df' % precision + precision = "%%.%df" % precision size = precision % (size / math.pow(base, m)) - return '%s%s %s%s' % (sign, size.strip(), multiples[m], unit) + return "%s%s %s%s" % (sign, size.strip(), multiples[m], unit) def _check_memory_usage(worker): @@ -339,8 +342,8 @@ def _check_memory_usage(worker): mem_usage = _get_process_rss() if mem_usage and mem_usage > _memory_max_usage: worker.log.info( - "memory usage %s > %s, forcing gc", - _format_data_size(mem_usage), _format_data_size(_memory_max_usage)) + "memory usage %s > %s, forcing gc", _format_data_size(mem_usage), _format_data_size(_memory_max_usage) + ) # Try to clean it up by forcing a full collection. gc.collect() mem_usage = _get_process_rss() @@ -348,7 +351,9 @@ def _check_memory_usage(worker): # Didn't clean up enough, we'll have to terminate. worker.log.warning( "memory usage %s > %s after gc, quitting", - _format_data_size(mem_usage), _format_data_size(_memory_max_usage)) + _format_data_size(mem_usage), + _format_data_size(_memory_max_usage), + ) # This will cause worker to auto-restart itself worker.alive = False worker._last_memory_check_time = time.time() @@ -364,8 +369,7 @@ def worker_int(worker): code = [] for thread_id, stack in sys._current_frames().items(): # noqa - code.append( - "\n# Thread: %s(%d)" % (get_thread_id(thread_id), thread_id)) + code.append("\n# Thread: %s(%d)" % (get_thread_id(thread_id), thread_id)) for fname, lineno, name, line in traceback.extract_stack(stack): code.append('File: "%s", line %d, in %s' % (fname, lineno, name)) if line: @@ -387,17 +391,21 @@ def child_exit(server, worker): def pre_request(worker, req): worker.start_time = time.time() - worker.log.debug( - "GNCRN PRE WORKER [cnt:%s]: %s %s", worker.nr, req.method, req.path) + worker.log.debug("GNCRN PRE WORKER [cnt:%s]: %s %s", worker.nr, req.method, req.path) def post_request(worker, req, environ, resp): total_time = time.time() - worker.start_time # Gunicorn sometimes has problems with reading the status_code - status_code = getattr(resp, 'status_code', '') + status_code = getattr(resp, "status_code", "") worker.log.debug( "GNCRN POST WORKER [cnt:%s]: %s %s resp: %s, Load Time: %.4fs", - worker.nr, req.method, req.path, status_code, total_time) + worker.nr, + req.method, + req.path, + status_code, + total_time, + ) _check_memory_usage(worker) @@ -410,8 +418,8 @@ def _filter_proxy(ip): :param ip: ip string from headers """ - if ',' in ip: - _ips = ip.split(',') + if "," in ip: + _ips = ip.split(",") _first_ip = _ips[0].strip() return _first_ip return ip @@ -427,8 +435,9 @@ def _filter_port(ip): :param ip: """ + def is_ipv6(ip_addr): - if hasattr(socket, 'inet_pton'): + if hasattr(socket, "inet_pton"): try: socket.inet_pton(socket.AF_INET6, ip_addr) except socket.error: @@ -437,24 +446,24 @@ def _filter_port(ip): return False return True - if ':' not in ip: # must be ipv4 pure ip + if ":" not in ip: # must be ipv4 pure ip return ip - if '[' in ip and ']' in ip: # ipv6 with port - return ip.split(']')[0][1:].lower() + if "[" in ip and "]" in ip: # ipv6 with port + return ip.split("]")[0][1:].lower() # must be ipv6 or ipv4 with port if is_ipv6(ip): return ip else: - ip, _port = ip.split(':')[:2] # means ipv4+port + ip, _port = ip.split(":")[:2] # means ipv4+port return ip def get_ip_addr(environ): - proxy_key = 'HTTP_X_REAL_IP' - proxy_key2 = 'HTTP_X_FORWARDED_FOR' - def_key = 'REMOTE_ADDR' + proxy_key = "HTTP_X_REAL_IP" + proxy_key2 = "HTTP_X_FORWARDED_FOR" + def_key = "REMOTE_ADDR" def _filters(x): return _filter_port(_filter_proxy(x)) @@ -467,7 +476,7 @@ def get_ip_addr(environ): if ip: return _filters(ip) - ip = environ.get(def_key, '0.0.0.0') + ip = environ.get(def_key, "0.0.0.0") return _filters(ip) @@ -482,43 +491,40 @@ class RhodeCodeLogger(Logger): Logger.__init__(self, cfg) def now(self): - """ return date in RhodeCode Log format """ + """return date in RhodeCode Log format""" now = time.time() msecs = int((now - int(now)) * 1000) - return time.strftime(self.datefmt, time.localtime(now)) + '.{0:03d}'.format(msecs) + return time.strftime(self.datefmt, time.localtime(now)) + ".{0:03d}".format(msecs) def atoms(self, resp, req, environ, request_time): - """ Gets atoms for log formatting. - """ + """Gets atoms for log formatting.""" status = resp.status if isinstance(status, str): status = status.split(None, 1)[0] atoms = { - 'h': get_ip_addr(environ), - 'l': '-', - 'u': self._get_user(environ) or '-', - 't': self.now(), - 'r': "%s %s %s" % (environ['REQUEST_METHOD'], - environ['RAW_URI'], - environ["SERVER_PROTOCOL"]), - 's': status, - 'm': environ.get('REQUEST_METHOD'), - 'U': environ.get('PATH_INFO'), - 'q': environ.get('QUERY_STRING'), - 'H': environ.get('SERVER_PROTOCOL'), - 'b': getattr(resp, 'sent', None) is not None and str(resp.sent) or '-', - 'B': getattr(resp, 'sent', None), - 'f': environ.get('HTTP_REFERER', '-'), - 'a': environ.get('HTTP_USER_AGENT', '-'), - 'T': request_time.seconds, - 'D': (request_time.seconds * 1000000) + request_time.microseconds, - 'M': (request_time.seconds * 1000) + int(request_time.microseconds/1000), - 'L': "%d.%06d" % (request_time.seconds, request_time.microseconds), - 'p': "<%s>" % os.getpid() + "h": get_ip_addr(environ), + "l": "-", + "u": self._get_user(environ) or "-", + "t": self.now(), + "r": "%s %s %s" % (environ["REQUEST_METHOD"], environ["RAW_URI"], environ["SERVER_PROTOCOL"]), + "s": status, + "m": environ.get("REQUEST_METHOD"), + "U": environ.get("PATH_INFO"), + "q": environ.get("QUERY_STRING"), + "H": environ.get("SERVER_PROTOCOL"), + "b": getattr(resp, "sent", None) is not None and str(resp.sent) or "-", + "B": getattr(resp, "sent", None), + "f": environ.get("HTTP_REFERER", "-"), + "a": environ.get("HTTP_USER_AGENT", "-"), + "T": request_time.seconds, + "D": (request_time.seconds * 1000000) + request_time.microseconds, + "M": (request_time.seconds * 1000) + int(request_time.microseconds / 1000), + "L": "%d.%06d" % (request_time.seconds, request_time.microseconds), + "p": "<%s>" % os.getpid(), } # add request headers - if hasattr(req, 'headers'): + if hasattr(req, "headers"): req_headers = req.headers else: req_headers = req diff --git a/conftest.py b/conftest.py index 445b00ea..dc80dade 100644 --- a/conftest.py +++ b/conftest.py @@ -16,13 +16,13 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -import pytest # noqa +import pytest # noqa # keep the imports to have a toplevel conftest.py but still importable from EE edition -from rhodecode.tests.conftest_common import ( # noqa +from rhodecode.tests.conftest_common import ( # noqa pytest_generate_tests, pytest_runtest_makereport, - pytest_addoption + pytest_addoption, ) @@ -36,13 +36,12 @@ pytest_plugins = [ def pytest_configure(config): - from rhodecode.config import patches # noqa + from rhodecode.config import patches # noqa def pytest_collection_modifyitems(session, config, items): # nottest marked, compare nose, used for transition from nose to pytest - remaining = [ - i for i in items if getattr(i.obj, '__test__', True)] + remaining = [i for i in items if getattr(i.obj, "__test__", True)] items[:] = remaining # NOTE(marcink): custom test ordering, db tests and vcstests are slowest and should @@ -50,9 +49,9 @@ def pytest_collection_modifyitems(session, config, items): def sorter(item): pos = 0 key = item._nodeid - if key.startswith('rhodecode/tests/database'): + if key.startswith("rhodecode/tests/database"): pos = 1 - elif key.startswith('rhodecode/tests/vcs_operations'): + elif key.startswith("rhodecode/tests/vcs_operations"): pos = 2 return pos diff --git a/docs/conf.py b/docs/conf.py index cddee16c..92aae03a 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -187,9 +187,9 @@ html_theme = "furo" # html_logo = None -#html_sidebars = { +# html_sidebars = { # "**": ["globaltoc.html"], -#} +# } # The name of an image file (within the static path) to use as favicon of the # docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 @@ -306,9 +306,7 @@ pdf_fit_mode = "truncate" # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [ - ("index", "rhodecodeenterprise", "RhodeCode Enterprise", ["RhodeCode GmbH"], 1) -] +man_pages = [("index", "rhodecodeenterprise", "RhodeCode Enterprise", ["RhodeCode GmbH"], 1)] # If true, show URL addresses after external links. # man_show_urls = False diff --git a/rhodecode/__init__.py b/rhodecode/__init__.py index 732b082b..0c62e827 100644 --- a/rhodecode/__init__.py +++ b/rhodecode/__init__.py @@ -23,20 +23,19 @@ import logging now = datetime.datetime.now() -now = now.strftime("%Y-%m-%d %H:%M:%S") + '.' + f"{int(now.microsecond/1000):03d}" +now = now.strftime("%Y-%m-%d %H:%M:%S") + "." + f"{int(now.microsecond / 1000):03d}" log = logging.getLogger(__name__) -log.debug(f'{now} Starting RhodeCode imports...') +log.debug(f"{now} Starting RhodeCode imports...") -VERSION = tuple(open(os.path.join( - os.path.dirname(__file__), 'VERSION')).read().strip().split('.')) +VERSION = tuple(open(os.path.join(os.path.dirname(__file__), "VERSION")).read().strip().split(".")) BACKENDS = collections.OrderedDict() -BACKENDS['hg'] = 'Mercurial repository' -BACKENDS['git'] = 'Git repository' -BACKENDS['svn'] = 'Subversion repository' +BACKENDS["hg"] = "Mercurial repository" +BACKENDS["git"] = "Git repository" +BACKENDS["svn"] = "Subversion repository" CELERY_ENABLED = False @@ -45,16 +44,18 @@ CELERY_EAGER = False # link to config for pyramid CONFIG = {} -class NotGivenMeta: +class NotGivenMeta: def __repr__(self): - return 'NotGivenObject()' + return "NotGivenObject()" + __str__ = __repr__ + NotGiven = NotGivenMeta() -class ConfigGet: +class ConfigGet: @classmethod def _get_val_or_missing(cls, key, missing): if key not in CONFIG: @@ -68,23 +69,27 @@ class ConfigGet: def get_str(self, key, missing=NotGiven): from rhodecode.lib.str_utils import safe_str + val = self._get_val_or_missing(key, missing) return safe_str(val) def get_int(self, key, missing=NotGiven): from rhodecode.lib.str_utils import safe_int + val = self._get_val_or_missing(key, missing) return safe_int(val) def get_bool(self, key, missing=NotGiven): from rhodecode.lib.type_utils import str2bool + val = self._get_val_or_missing(key, missing) return str2bool(val) def get_list(self, key, missing=NotGiven): from rhodecode.lib.type_utils import aslist + val = self._get_val_or_missing(key, missing) - return aslist(val, sep=',') + return aslist(val, sep=",") # Populated with the settings dictionary from application init in @@ -94,11 +99,11 @@ PYRAMID_SETTINGS = {} # Linked module for extensions EXTENSIONS = {} -__version__ = ('.'.join((str(each) for each in VERSION[:3]))) +__version__ = ".".join((str(each) for each in VERSION[:3])) __dbversion__ = 115 # defines current db version for migrations -__license__ = 'AGPLv3, and Commercial License' -__author__ = 'RhodeCode GmbH' -__url__ = 'https://code.rhodecode.com' +__license__ = "AGPLv3, and Commercial License" +__author__ = "RhodeCode GmbH" +__url__ = "https://code.rhodecode.com" -is_test = os.getenv('RC_TEST', '0') == '1' +is_test = os.getenv("RC_TEST", "0") == "1" disable_error_handler = False diff --git a/rhodecode/api/__init__.py b/rhodecode/api/__init__.py index 3262051a..44923e75 100644 --- a/rhodecode/api/__init__.py +++ b/rhodecode/api/__init__.py @@ -30,8 +30,7 @@ from pyramid.renderers import render from pyramid.response import Response from pyramid.httpexceptions import HTTPNotFound -from rhodecode.api.exc import ( - JSONRPCBaseError, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError) +from rhodecode.api.exc import JSONRPCBaseError, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError from rhodecode.apps._base import TemplateArgs from rhodecode.lib.auth import AuthUser from rhodecode.lib.base import get_ip_addr, attach_context_attributes @@ -44,9 +43,9 @@ from rhodecode.config.patches import inspect_getargspec log = logging.getLogger(__name__) -DEFAULT_RENDERER = 'jsonrpc_renderer' -DEFAULT_URL = '/_admin/api' -SERVICE_API_IDENTIFIER = 'service_' +DEFAULT_RENDERER = "jsonrpc_renderer" +DEFAULT_URL = "/_admin/api" +SERVICE_API_IDENTIFIER = "service_" def find_methods(jsonrpc_methods, pattern): @@ -56,7 +55,7 @@ def find_methods(jsonrpc_methods, pattern): for single_pattern in pattern: for method_name, method in filter( - lambda x: not x[0].startswith(SERVICE_API_IDENTIFIER), jsonrpc_methods.items() + lambda x: not x[0].startswith(SERVICE_API_IDENTIFIER), jsonrpc_methods.items() ): if fnmatch.fnmatch(method_name, single_pattern): matches[method_name] = method @@ -73,17 +72,17 @@ class ExtJsonRenderer(object): self.serializer = ext_json.formatted_json def __call__(self, info): - """ Returns a plain JSON-encoded string with content-type + """Returns a plain JSON-encoded string with content-type ``application/json``. The content-type may be overridden by setting ``request.response.content_type``.""" def _render(value, system): - request = system.get('request') + request = system.get("request") if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: - response.content_type = 'application/json' + response.content_type = "application/json" return self.serializer(value) @@ -91,28 +90,22 @@ class ExtJsonRenderer(object): def jsonrpc_response(request, result): - rpc_id = getattr(request, 'rpc_id', None) + rpc_id = getattr(request, "rpc_id", None) - ret_value = '' + ret_value = "" if rpc_id: - ret_value = {'id': rpc_id, 'result': result, 'error': None} + ret_value = {"id": rpc_id, "result": result, "error": None} # fetch deprecation warnings, and store it inside results - deprecation = getattr(request, 'rpc_deprecation', None) + deprecation = getattr(request, "rpc_deprecation", None) if deprecation: - ret_value['DEPRECATION_WARNING'] = deprecation + ret_value["DEPRECATION_WARNING"] = deprecation raw_body = render(DEFAULT_RENDERER, ret_value, request=request) - content_type = 'application/json' - content_type_header = 'Content-Type' - headers = { - content_type_header: content_type - } - return Response( - body=raw_body, - content_type=content_type, - headerlist=[(k, v) for k, v in headers.items()] - ) + content_type = "application/json" + content_type_header = "Content-Type" + headers = {content_type_header: content_type} + return Response(body=raw_body, content_type=content_type, headerlist=[(k, v) for k, v in headers.items()]) def jsonrpc_error(request, message, retid=None, code: int | None = None, headers: dict | None = None): @@ -120,24 +113,21 @@ def jsonrpc_error(request, message, retid=None, code: int | None = None, headers Generate a Response object with a JSON-RPC error body """ headers = headers or {} - content_type = 'application/json' - content_type_header = 'Content-Type' + content_type = "application/json" + content_type_header = "Content-Type" if content_type_header not in headers: headers[content_type_header] = content_type - err_dict = {'id': retid, 'result': None, 'error': message} + err_dict = {"id": retid, "result": None, "error": message} raw_body = render(DEFAULT_RENDERER, err_dict, request=request) return Response( - body=raw_body, - status=code, - content_type=content_type, - headerlist=[(k, v) for k, v in headers.items()] + body=raw_body, status=code, content_type=content_type, headerlist=[(k, v) for k, v in headers.items()] ) def exception_view(exc, request): - rpc_id = getattr(request, 'rpc_id', None) + rpc_id = getattr(request, "rpc_id", None) if isinstance(exc, JSONRPCError): fault_message = safe_str(exc) @@ -148,35 +138,36 @@ def exception_view(exc, request): fault_message = colander_exc.asdict() log.debug('json-rpc colander error rpc_id:%s "%s"', rpc_id, fault_message) elif isinstance(exc, JSONRPCForbidden): - fault_message = 'Access was denied to this resource.' + fault_message = "Access was denied to this resource." log.warning('json-rpc forbidden call rpc_id:%s "%s"', rpc_id, fault_message) elif isinstance(exc, HTTPNotFound): method = request.rpc_method - log.debug('json-rpc method `%s` not found in list of ' - 'api calls: %s, rpc_id:%s', - method, list(request.registry.jsonrpc_methods.keys()), rpc_id) + log.debug( + "json-rpc method `%s` not found in list of api calls: %s, rpc_id:%s", + method, + list(request.registry.jsonrpc_methods.keys()), + rpc_id, + ) - similar = 'none' + similar = "none" try: - similar_paterns = [f'*{x}*' for x in method.split('_')] - similar_found = find_methods( - request.registry.jsonrpc_methods, similar_paterns) - similar = ', '.join(similar_found.keys()) or similar + similar_paterns = [f"*{x}*" for x in method.split("_")] + similar_found = find_methods(request.registry.jsonrpc_methods, similar_paterns) + similar = ", ".join(similar_found.keys()) or similar except Exception: # make the whole above block safe pass fault_message = f"No such method: {method}. Similar methods: {similar}" else: - fault_message = 'undefined error' + fault_message = "undefined error" exc_info = exc.exc_info() - store_exception(id(exc_info), exc_info, prefix='rhodecode-api') + store_exception(id(exc_info), exc_info, prefix="rhodecode-api") statsd = request.registry.statsd if statsd: exc_type = f"{exc.__class__.__module__}.{exc.__class__.__name__}" - statsd.incr('rhodecode_exception_total', - tags=["exc_source:api", f"type:{exc_type}"]) + statsd.incr("rhodecode_exception_total", tags=["exc_source:api", f"type:{exc_type}"]) return jsonrpc_error(request, fault_message, rpc_id) @@ -196,49 +187,42 @@ def request_view(request): api_user = User.get_by_auth_token(request.rpc_api_key) if api_user is None: - return jsonrpc_error( - request, retid=request.rpc_id, message='Invalid API KEY') + return jsonrpc_error(request, retid=request.rpc_id, message="Invalid API KEY") if not api_user.active: - return jsonrpc_error( - request, retid=request.rpc_id, - message='Request from this user not allowed') + return jsonrpc_error(request, retid=request.rpc_id, message="Request from this user not allowed") # check if we are allowed to use this IP - auth_u = AuthUser( - api_user.user_id, request.rpc_api_key, ip_addr=request.rpc_ip_addr) + auth_u = AuthUser(api_user.user_id, request.rpc_api_key, ip_addr=request.rpc_ip_addr) if not auth_u.ip_allowed: return jsonrpc_error( - request, retid=request.rpc_id, - message='Request from IP:{} not allowed'.format( - request.rpc_ip_addr)) + request, retid=request.rpc_id, message="Request from IP:{} not allowed".format(request.rpc_ip_addr) + ) else: - log.info('Access for IP:%s allowed', request.rpc_ip_addr) + log.info("Access for IP:%s allowed", request.rpc_ip_addr) # register our auth-user request.rpc_user = auth_u - request.environ['rc_auth_user_id'] = str(auth_u.user_id) + request.environ["rc_auth_user_id"] = str(auth_u.user_id) # now check if token is valid for API auth_token = request.rpc_api_key - token_match = api_user.authenticate_by_token( - auth_token, roles=[UserApiKeys.ROLE_API]) + token_match = api_user.authenticate_by_token(auth_token, roles=[UserApiKeys.ROLE_API]) invalid_token = not token_match - log.debug('Checking if API KEY is valid with proper role') + log.debug("Checking if API KEY is valid with proper role") if invalid_token: return jsonrpc_error( - request, retid=request.rpc_id, - message='API KEY invalid or, has bad role for an API call') + request, retid=request.rpc_id, message="API KEY invalid or, has bad role for an API call" + ) else: - auth_u = 'service' - if request.rpc_api_key != request.registry.settings['app.service_api.token']: + auth_u = "service" + if request.rpc_api_key != request.registry.settings["app.service_api.token"]: raise Exception("Provided service secret is not recognized!") except Exception: - log.exception('Error on API AUTH') - return jsonrpc_error( - request, retid=request.rpc_id, message='Invalid API KEY') + log.exception("Error on API AUTH") + return jsonrpc_error(request, retid=request.rpc_id, message="Invalid API KEY") method = request.rpc_method func = request.registry.jsonrpc_methods[method] @@ -253,21 +237,20 @@ def request_view(request): default_empty = type(NotImplemented) # kw arguments required by this method - func_kwargs = dict(itertools.zip_longest( - reversed(arglist), reversed(defaults), fillvalue=default_empty)) + func_kwargs = dict(itertools.zip_longest(reversed(arglist), reversed(defaults), fillvalue=default_empty)) # This attribute will need to be first param of a method that uses # api_key, which is translated to instance of user at that name - user_var = 'apiuser' - request_var = 'request' + user_var = "apiuser" + request_var = "request" for arg in [user_var, request_var]: if arg not in arglist: return jsonrpc_error( request, retid=request.rpc_id, - message='This method [%s] does not support ' - 'required parameter `%s`' % (func.__name__, arg)) + message="This method [%s] does not support required parameter `%s`" % (func.__name__, arg), + ) # get our arglist and check if we provided them as args for arg, default in func_kwargs.items(): @@ -280,9 +263,7 @@ def request_view(request): # NotImplementedType (default_empty) if default == default_empty and arg not in request.rpc_params: return jsonrpc_error( - request, - retid=request.rpc_id, - message=('Missing non optional `%s` arg in JSON DATA' % arg) + request, retid=request.rpc_id, message=("Missing non optional `%s` arg in JSON DATA" % arg) ) # sanitize extra passed arguments @@ -291,13 +272,10 @@ def request_view(request): del request.rpc_params[k] call_params = request.rpc_params - call_params.update({ - 'request': request, - 'apiuser': auth_u - }) + call_params.update({"request": request, "apiuser": auth_u}) # register some common functions for usage - rpc_user = request.rpc_user.user_id if hasattr(request, 'rpc_user') else None + rpc_user = request.rpc_user.user_id if hasattr(request, "rpc_user") else None attach_context_attributes(TemplateArgs(), request, rpc_user) statsd = request.registry.statsd @@ -306,24 +284,18 @@ def request_view(request): ret_value = func(**call_params) resp = jsonrpc_response(request, ret_value) if statsd: - statsd.incr('rhodecode_api_call_success_total') + statsd.incr("rhodecode_api_call_success_total") return resp except JSONRPCBaseError: raise except Exception: - log.exception('Unhandled exception occurred on api call: %s', func) + log.exception("Unhandled exception occurred on api call: %s", func) exc_info = sys.exc_info() - exc_id, exc_type_name = store_exception( - id(exc_info), exc_info, prefix='rhodecode-api') - error_headers = { - 'RhodeCode-Exception-Id': str(exc_id), - 'RhodeCode-Exception-Type': str(exc_type_name) - } - err_resp = jsonrpc_error( - request, retid=request.rpc_id, message='Internal server error', - headers=error_headers) + exc_id, exc_type_name = store_exception(id(exc_info), exc_info, prefix="rhodecode-api") + error_headers = {"RhodeCode-Exception-Id": str(exc_id), "RhodeCode-Exception-Type": str(exc_type_name)} + err_resp = jsonrpc_error(request, retid=request.rpc_id, message="Internal server error", headers=error_headers) if statsd: - statsd.incr('rhodecode_api_call_fail_total') + statsd.incr("rhodecode_api_call_fail_total") return err_resp @@ -336,21 +308,20 @@ def setup_request(request): user. """ - log.debug('Executing setup request: %r', request) + log.debug("Executing setup request: %r", request) request.rpc_ip_addr = get_ip_addr(request.environ) # TODO(marcink): deprecate GET at some point - if request.method not in ['POST', 'GET']: + if request.method not in ["POST", "GET"]: log.debug('unsupported request method "%s"', request.method) - raise JSONRPCError( - 'unsupported request method "%s". Please use POST' % request.method) + raise JSONRPCError('unsupported request method "%s". Please use POST' % request.method) - if 'CONTENT_LENGTH' not in request.environ: + if "CONTENT_LENGTH" not in request.environ: log.debug("No Content-Length") raise JSONRPCError("Empty body, No Content-Length in request") else: - length = request.environ['CONTENT_LENGTH'] - log.debug('Content-Length: %s', length) + length = request.environ["CONTENT_LENGTH"] + log.debug("Content-Length: %s", length) if length == 0: log.debug("Content-Length is 0") @@ -364,32 +335,34 @@ def setup_request(request): # catch JSON errors Here raise JSONRPCError(f"JSON parse error ERR:{e} RAW:{raw_body!r}") - request.rpc_id = json_body.get('id') - request.rpc_method = json_body.get('method') + request.rpc_id = json_body.get("id") + request.rpc_method = json_body.get("method") # check required base parameters try: - api_key = json_body.get('api_key') + api_key = json_body.get("api_key") if not api_key: - api_key = json_body.get('auth_token') + api_key = json_body.get("auth_token") if not api_key: - raise KeyError('api_key or auth_token') + raise KeyError("api_key or auth_token") # TODO(marcink): support passing in token in request header request.rpc_api_key = api_key - request.rpc_id = json_body['id'] - request.rpc_method = json_body['method'] - request.rpc_params = json_body['args'] \ - if isinstance(json_body['args'], dict) else {} + request.rpc_id = json_body["id"] + request.rpc_method = json_body["method"] + request.rpc_params = json_body["args"] if isinstance(json_body["args"], dict) else {} - log.debug('method: %s, params: %.10240r', request.rpc_method, request.rpc_params) + log.debug("method: %s, params: %.10240r", request.rpc_method, request.rpc_params) except KeyError as e: - raise JSONRPCError(f'Incorrect JSON data. Missing {e}') + raise JSONRPCError(f"Incorrect JSON data. Missing {e}") - log.debug('setup complete, now handling method:%s rpcid:%s', - request.rpc_method, request.rpc_id, ) + log.debug( + "setup complete, now handling method:%s rpcid:%s", + request.rpc_method, + request.rpc_id, + ) class RoutePredicate(object): @@ -397,7 +370,7 @@ class RoutePredicate(object): self.val = val def text(self): - return f'jsonrpc route = {self.val}' + return f"jsonrpc route = {self.val}" phash = text @@ -417,12 +390,12 @@ class NotFoundPredicate(object): self.methods = config.registry.jsonrpc_methods def text(self): - return f'jsonrpc method not found = {self.val}' + return f"jsonrpc method not found = {self.val}" phash = text def __call__(self, info, request): - return hasattr(request, 'rpc_method') + return hasattr(request, "rpc_method") class MethodPredicate(object): @@ -430,36 +403,35 @@ class MethodPredicate(object): self.method = val def text(self): - return f'jsonrpc method = {self.method}' + return f"jsonrpc method = {self.method}" phash = text def __call__(self, context, request): # we need to explicitly return False here, so pyramid doesn't try to # execute our view directly. We need our main handler to execute things - return getattr(request, 'rpc_method') == self.method + return getattr(request, "rpc_method") == self.method def add_jsonrpc_method(config, view, **kwargs): # pop the method name - method = kwargs.pop('method', None) + method = kwargs.pop("method", None) if method is None: - raise ConfigurationError( - 'Cannot register a JSON-RPC method without specifying the "method"') + raise ConfigurationError('Cannot register a JSON-RPC method without specifying the "method"') # we define custom predicate, to enable to detect conflicting methods, # those predicates are kind of "translation" from the decorator variables # to internal predicates names - kwargs['jsonrpc_method'] = method + kwargs["jsonrpc_method"] = method # register our view into global view store for validation config.registry.jsonrpc_methods[method] = view # we're using our main request_view handler, here, so each method # has a unified handler for itself - config.add_view(request_view, route_name='apiv2', **kwargs) + config.add_view(request_view, route_name="apiv2", **kwargs) class jsonrpc_method(object): @@ -476,20 +448,19 @@ class jsonrpc_method(object): def __call__(self, wrapped): kwargs = self.kwargs.copy() - kwargs['method'] = self.method or wrapped.__name__ - depth = kwargs.pop('_depth', 0) + kwargs["method"] = self.method or wrapped.__name__ + depth = kwargs.pop("_depth", 0) def callback(context, name, ob): config = context.config.with_package(info.module) config.add_jsonrpc_method(view=ob, **kwargs) - info = venusian.attach(wrapped, callback, category='pyramid', - depth=depth + 1) - if info.scope == 'class': + info = venusian.attach(wrapped, callback, category="pyramid", depth=depth + 1) + if info.scope == "class": # ensure that attr is set if decorating a class method - kwargs.setdefault('attr', wrapped.__name__) + kwargs.setdefault("attr", wrapped.__name__) - kwargs['_info'] = info.codeinfo # fbo action_method + kwargs["_info"] = info.codeinfo # fbo action_method return wrapped @@ -514,11 +485,10 @@ class jsonrpc_deprecated_method(object): def __init__(self, use_method, deprecated_at_version): self.use_method = use_method self.deprecated_at_version = deprecated_at_version - self.deprecated_msg = '' + self.deprecated_msg = "" def __call__(self, func): - self.deprecated_msg = 'Please use method `{method}` instead.'.format( - method=self.use_method) + self.deprecated_msg = "Please use method `{method}` instead.".format(method=self.use_method) docstring = """\n .. deprecated:: {version} @@ -528,51 +498,55 @@ class jsonrpc_deprecated_method(object): {original_docstring} """ func.__doc__ = docstring.format( - version=self.deprecated_at_version, - deprecation_message=self.deprecated_msg, - original_docstring=func.__doc__) + version=self.deprecated_at_version, deprecation_message=self.deprecated_msg, original_docstring=func.__doc__ + ) return decorator.decorator(self.__wrapper, func) def __wrapper(self, func, *fargs, **fkwargs): - log.warning('DEPRECATED API CALL on function %s, please ' - 'use `%s` instead', func, self.use_method) + log.warning("DEPRECATED API CALL on function %s, please use `%s` instead", func, self.use_method) # alter function docstring to mark as deprecated, this is picked up # via fabric file that generates API DOC. result = func(*fargs, **fkwargs) request = fargs[0] - request.rpc_deprecation = 'DEPRECATED METHOD ' + self.deprecated_msg + request.rpc_deprecation = "DEPRECATED METHOD " + self.deprecated_msg return result def add_api_methods(config): from rhodecode.api.views import ( - deprecated_api, gist_api, pull_request_api, repo_api, repo_group_api, - server_api, search_api, testing_api, user_api, user_group_api) + deprecated_api, + gist_api, + pull_request_api, + repo_api, + repo_group_api, + server_api, + search_api, + testing_api, + user_api, + user_group_api, + ) - config.scan('rhodecode.api.views') + config.scan("rhodecode.api.views") def includeme(config): - plugin_module = 'rhodecode.api' - plugin_settings = get_plugin_settings( - plugin_module, config.registry.settings) + plugin_module = "rhodecode.api" + plugin_settings = get_plugin_settings(plugin_module, config.registry.settings) - if not hasattr(config.registry, 'jsonrpc_methods'): + if not hasattr(config.registry, "jsonrpc_methods"): config.registry.jsonrpc_methods = OrderedDict() # match filter by given method only - config.add_view_predicate('jsonrpc_method', MethodPredicate) - config.add_view_predicate('jsonrpc_method_not_found', NotFoundPredicate) + config.add_view_predicate("jsonrpc_method", MethodPredicate) + config.add_view_predicate("jsonrpc_method_not_found", NotFoundPredicate) config.add_renderer(DEFAULT_RENDERER, ExtJsonRenderer()) - config.add_directive('add_jsonrpc_method', add_jsonrpc_method) + config.add_directive("add_jsonrpc_method", add_jsonrpc_method) - config.add_route_predicate( - 'jsonrpc_call', RoutePredicate) + config.add_route_predicate("jsonrpc_call", RoutePredicate) - config.add_route( - 'apiv2', plugin_settings.get('url', DEFAULT_URL), jsonrpc_call=True) + config.add_route("apiv2", plugin_settings.get("url", DEFAULT_URL), jsonrpc_call=True) # register some exception handling view config.add_view(exception_view, context=JSONRPCBaseError) diff --git a/rhodecode/api/exc.py b/rhodecode/api/exc.py index a93b0636..179ce609 100644 --- a/rhodecode/api/exc.py +++ b/rhodecode/api/exc.py @@ -18,7 +18,7 @@ class JSONRPCBaseError(Exception): - def __init__(self, message='', *args): + def __init__(self, message="", *args): self.message = message super().__init__(message, *args) @@ -28,13 +28,10 @@ class JSONRPCError(JSONRPCBaseError): class JSONRPCValidationError(JSONRPCBaseError): - def __init__(self, *args, **kwargs): - self.colander_exception = kwargs.pop('colander_exc') - super().__init__( - message=self.colander_exception, *args) + self.colander_exception = kwargs.pop("colander_exc") + super().__init__(message=self.colander_exception, *args) class JSONRPCForbidden(JSONRPCBaseError): pass - diff --git a/rhodecode/api/tests/conftest.py b/rhodecode/api/tests/conftest.py index dcd34619..4cb7e557 100644 --- a/rhodecode/api/tests/conftest.py +++ b/rhodecode/api/tests/conftest.py @@ -34,16 +34,11 @@ def testuser_api(request, baseapp): # REGULAR USER cls.test_user = UserModel().create_or_update( - username='test-api', - password='test', - email='test@api.rhodecode.org', - firstname='first', - lastname='last' + username="test-api", password="test", email="test@api.rhodecode.org", firstname="first", lastname="last" ) # create TOKEN for user, if he doesn't have one if not cls.test_user.api_key: - AuthTokenModel().create( - user=cls.test_user, description='TEST_USER_TOKEN') + AuthTokenModel().create(user=cls.test_user, description="TEST_USER_TOKEN") Session().commit() cls.TEST_USER_LOGIN = cls.test_user.username diff --git a/rhodecode/api/tests/test_add_field_to_repo.py b/rhodecode/api/tests/test_add_field_to_repo.py index 3b9f1fc8..599261c7 100644 --- a/rhodecode/api/tests/test_add_field_to_repo.py +++ b/rhodecode/api/tests/test_add_field_to_repo.py @@ -19,8 +19,7 @@ import pytest from rhodecode.model.db import Repository, RepositoryField -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error @pytest.mark.usefixtures("testuser_api", "app") @@ -29,32 +28,35 @@ class TestAddFieldToRepo(object): repo = backend.create_repo() repo_name = repo.repo_name id_, params = build_data( - self.apikey, 'add_field_to_repo', + self.apikey, + "add_field_to_repo", repoid=repo_name, - key='extra_field', - label='extra_field_label', - description='extra_field_desc') + key="extra_field", + label="extra_field_label", + description="extra_field_desc", + ) response = api_call(self.app, params) expected = { - 'msg': 'Added new repository field `extra_field`', - 'success': True, + "msg": "Added new repository field `extra_field`", + "success": True, } assert_ok(id_, expected, given=response.body) repo = Repository.get_by_repo_name(repo_name) - repo_field = RepositoryField.get_by_key_name('extra_field', repo) + repo_field = RepositoryField.get_by_key_name("extra_field", repo) _data = repo_field.get_dict() - assert _data['field_desc'] == 'extra_field_desc' - assert _data['field_key'] == 'extra_field' - assert _data['field_label'] == 'extra_field_label' + assert _data["field_desc"] == "extra_field_desc" + assert _data["field_key"] == "extra_field" + assert _data["field_label"] == "extra_field_label" id_, params = build_data( - self.apikey, 'add_field_to_repo', + self.apikey, + "add_field_to_repo", repoid=repo_name, - key='extra_field', - label='extra_field_label', - description='extra_field_desc') + key="extra_field", + label="extra_field_label", + description="extra_field_desc", + ) response = api_call(self.app, params) - expected = 'Field with key `extra_field` exists for repo `%s`' % ( - repo_name) + expected = "Field with key `extra_field` exists for repo `%s`" % (repo_name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_add_user_to_user_group.py b/rhodecode/api/tests/test_add_user_to_user_group.py index a7a4c469..b8576aa8 100644 --- a/rhodecode/api/tests/test_add_user_to_user_group.py +++ b/rhodecode/api/tests/test_add_user_to_user_group.py @@ -20,8 +20,7 @@ import mock import pytest from rhodecode.model.user_group import UserGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") @@ -31,40 +30,28 @@ class TestAddUserToUserGroup(object): user = user_util.create_user() group_name = group.users_group_name user_name = user.username - id_, params = build_data( - self.apikey, 'add_user_to_user_group', - usergroupid=group_name, userid=user_name) + id_, params = build_data(self.apikey, "add_user_to_user_group", usergroupid=group_name, userid=user_name) response = api_call(self.app, params) - expected = { - 'msg': 'added member `%s` to user group `%s`' % ( - user_name, group_name - ), - 'success': True - } + expected = {"msg": "added member `%s` to user group `%s`" % (user_name, group_name), "success": True} assert_ok(id_, expected, given=response.body) def test_api_add_user_to_user_group_that_doesnt_exist(self, user_util): user = user_util.create_user() user_name = user.username - id_, params = build_data( - self.apikey, 'add_user_to_user_group', - usergroupid='false-group', - userid=user_name) + id_, params = build_data(self.apikey, "add_user_to_user_group", usergroupid="false-group", userid=user_name) response = api_call(self.app, params) - expected = 'user group `%s` does not exist' % 'false-group' + expected = "user group `%s` does not exist" % "false-group" assert_error(id_, expected, given=response.body) - @mock.patch.object(UserGroupModel, 'add_user_to_group', crash) + @mock.patch.object(UserGroupModel, "add_user_to_group", crash) def test_api_add_user_to_user_group_exception_occurred(self, user_util): group = user_util.create_user_group() user = user_util.create_user() group_name = group.users_group_name user_name = user.username - id_, params = build_data( - self.apikey, 'add_user_to_user_group', - usergroupid=group_name, userid=user_name) + id_, params = build_data(self.apikey, "add_user_to_user_group", usergroupid=group_name, userid=user_name) response = api_call(self.app, params) - expected = 'failed to add member to user group `%s`' % (group_name,) + expected = "failed to add member to user group `%s`" % (group_name,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_api.py b/rhodecode/api/tests/test_api.py index 48d01e93..c50ff04b 100644 --- a/rhodecode/api/tests/test_api.py +++ b/rhodecode/api/tests/test_api.py @@ -19,8 +19,7 @@ import pytest from rhodecode.api.utils import Optional, OAttr -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") @@ -28,72 +27,73 @@ class TestApi(object): maxDiff = None def test_Optional_object(self): - option1 = Optional(None) - assert ''.format(None) == repr(option1) + assert "".format(None) == repr(option1) assert option1() is None assert 1 == Optional.extract(Optional(1)) - assert 'example' == Optional.extract('example') + assert "example" == Optional.extract("example") def test_Optional_OAttr(self): - option1 = Optional(OAttr('apiuser')) - assert 'apiuser' == Optional.extract(option1) + option1 = Optional(OAttr("apiuser")) + assert "apiuser" == Optional.extract(option1) def test_OAttr_object(self): - oattr1 = OAttr('apiuser') - assert '' == repr(oattr1) + oattr1 = OAttr("apiuser") + assert "" == repr(oattr1) assert oattr1() == oattr1 def test_api_wrong_key(self): - id_, params = build_data('trololo', 'get_user') + id_, params = build_data("trololo", "get_user") response = api_call(self.app, params) - expected = 'Invalid API KEY' + expected = "Invalid API KEY" assert_error(id_, expected, given=response.body) def test_api_missing_non_optional_param(self): - id_, params = build_data(self.apikey, 'get_repo') + id_, params = build_data(self.apikey, "get_repo") response = api_call(self.app, params) - expected = 'Missing non optional `repoid` arg in JSON DATA' + expected = "Missing non optional `repoid` arg in JSON DATA" assert_error(id_, expected, given=response.body) def test_api_missing_non_optional_param_args_null(self): - id_, params = build_data(self.apikey, 'get_repo') + id_, params = build_data(self.apikey, "get_repo") params = params.replace(b'"args": {}', b'"args": null') response = api_call(self.app, params) - expected = 'Missing non optional `repoid` arg in JSON DATA' + expected = "Missing non optional `repoid` arg in JSON DATA" assert_error(id_, expected, given=response.body) def test_api_missing_non_optional_param_args_bad(self): - id_, params = build_data(self.apikey, 'get_repo') + id_, params = build_data(self.apikey, "get_repo") params = params.replace(b'"args": {}', b'"args": 1') response = api_call(self.app, params) - expected = 'Missing non optional `repoid` arg in JSON DATA' + expected = "Missing non optional `repoid` arg in JSON DATA" assert_error(id_, expected, given=response.body) def test_api_non_existing_method(self, request): - id_, params = build_data(self.apikey, 'not_existing', args='xx') + id_, params = build_data(self.apikey, "not_existing", args="xx") response = api_call(self.app, params) - expected = 'No such method: not_existing. Similar methods: none' + expected = "No such method: not_existing. Similar methods: none" assert_error(id_, expected, given=response.body) def test_api_non_existing_method_have_similar(self, request): - id_, params = build_data(self.apikey, 'comment', args='xx') + id_, params = build_data(self.apikey, "comment", args="xx") response = api_call(self.app, params) - expected = 'No such method: comment. ' \ - 'Similar methods: changeset_comment, comment_pull_request, ' \ - 'get_pull_request_comments, comment_commit, edit_comment, ' \ - 'get_comment, get_repo_comments' + expected = ( + "No such method: comment. " + "Similar methods: changeset_comment, comment_pull_request, " + "get_pull_request_comments, comment_commit, edit_comment, " + "get_comment, get_repo_comments" + ) assert_error(id_, expected, given=response.body) def test_api_disabled_user(self, request): - def set_active(active): from rhodecode.model.db import Session, User + user = User.get_by_auth_token(self.apikey) user.active = active Session().add(user) @@ -102,31 +102,34 @@ class TestApi(object): request.addfinalizer(lambda: set_active(True)) set_active(False) - id_, params = build_data(self.apikey, 'test', args='xx') + id_, params = build_data(self.apikey, "test", args="xx") response = api_call(self.app, params) - expected = 'Request from this user not allowed' + expected = "Request from this user not allowed" assert_error(id_, expected, given=response.body) def test_api_args_is_null(self): - __, params = build_data(self.apikey, 'get_users', ) + __, params = build_data( + self.apikey, + "get_users", + ) params = params.replace(b'"args": {}', b'"args": null') response = api_call(self.app, params) - assert response.status == '200 OK' + assert response.status == "200 OK" def test_api_args_is_bad(self): - __, params = build_data(self.apikey, 'get_users', ) + __, params = build_data( + self.apikey, + "get_users", + ) params = params.replace(b'"args": {}', b'"args": 1') response = api_call(self.app, params) - assert response.status == '200 OK' + assert response.status == "200 OK" def test_api_args_different_args(self): import string - expected = { - 'ascii_letters': string.ascii_letters, - 'ws': string.whitespace, - 'printables': string.printable - } - id_, params = build_data(self.apikey, 'test', args=expected) + + expected = {"ascii_letters": string.ascii_letters, "ws": string.whitespace, "printables": string.printable} + id_, params = build_data(self.apikey, "test", args=expected) response = api_call(self.app, params) - assert response.status == '200 OK' + assert response.status == "200 OK" assert_ok(id_, expected, response.body) diff --git a/rhodecode/api/tests/test_cleanup_repos.py b/rhodecode/api/tests/test_cleanup_repos.py index 8a2e29c7..3653a042 100644 --- a/rhodecode/api/tests/test_cleanup_repos.py +++ b/rhodecode/api/tests/test_cleanup_repos.py @@ -20,25 +20,26 @@ import mock import pytest from rhodecode.model.scm import ScmModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash @pytest.mark.usefixtures("testuser_api", "app") class TestCleanupRepos(object): def test_api_cleanup_repos(self): - id_, params = build_data(self.apikey, 'cleanup_repos') + id_, params = build_data(self.apikey, "cleanup_repos") response = api_call(self.app, params) - expected = {'removed': [], 'errors': []} + expected = {"removed": [], "errors": []} assert_ok(id_, expected, given=response.body) def test_api_cleanup_repos_error(self): + id_, params = build_data( + self.apikey, + "cleanup_repos", + ) - id_, params = build_data(self.apikey, 'cleanup_repos', ) - - with mock.patch('rhodecode.lib.utils.repo2db_cleanup', side_effect=crash): + with mock.patch("rhodecode.lib.utils.repo2db_cleanup", side_effect=crash): response = api_call(self.app, params) - expected = 'Error occurred during repo storage cleanup action' + expected = "Error occurred during repo storage cleanup action" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_cleanup_sessions.py b/rhodecode/api/tests/test_cleanup_sessions.py index bfc09662..2e874556 100644 --- a/rhodecode/api/tests/test_cleanup_sessions.py +++ b/rhodecode/api/tests/test_cleanup_sessions.py @@ -20,23 +20,25 @@ import mock import pytest from rhodecode.lib.user_sessions import FileAuthSessions -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash @pytest.mark.usefixtures("testuser_api", "app") class TestCleanupSessions(object): def test_api_cleanup_sessions(self): - id_, params = build_data(self.apikey, 'cleanup_sessions') + id_, params = build_data(self.apikey, "cleanup_sessions") response = api_call(self.app, params) - expected = {'backend': 'file sessions', 'sessions_removed': 0} + expected = {"backend": "file sessions", "sessions_removed": 0} assert_ok(id_, expected, given=response.body) - @mock.patch.object(FileAuthSessions, 'clean_sessions', crash) + @mock.patch.object(FileAuthSessions, "clean_sessions", crash) def test_api_cleanup_error(self): - id_, params = build_data(self.apikey, 'cleanup_sessions', ) + id_, params = build_data( + self.apikey, + "cleanup_sessions", + ) response = api_call(self.app, params) - expected = 'Error occurred during session cleanup' + expected = "Error occurred during session cleanup" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_close_pull_request.py b/rhodecode/api/tests/test_close_pull_request.py index c2017ce9..b9064039 100644 --- a/rhodecode/api/tests/test_close_pull_request.py +++ b/rhodecode/api/tests/test_close_pull_request.py @@ -21,13 +21,11 @@ import pytest from rhodecode.model.db import UserLog from rhodecode.model.pull_request import PullRequestModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestClosePullRequest(object): - @pytest.mark.backends("git", "hg") def test_api_close_pull_request(self, pr_util): pull_request = pr_util.create_pull_request() @@ -35,77 +33,81 @@ class TestClosePullRequest(object): author = pull_request.user_id repo = pull_request.target_repo.repo_id id_, params = build_data( - self.apikey, 'close_pull_request', + self.apikey, + "close_pull_request", repoid=pull_request.target_repo.repo_name, - pullrequestid=pull_request.pull_request_id) + pullrequestid=pull_request.pull_request_id, + ) response = api_call(self.app, params) expected = { - 'pull_request_id': pull_request_id, - 'close_status': 'Rejected', - 'closed': True, + "pull_request_id": pull_request_id, + "close_status": "Rejected", + "closed": True, } assert_ok(id_, expected, response.body) - journal = UserLog.query()\ - .filter(UserLog.user_id == author) \ - .order_by(UserLog.user_log_id.asc()) \ - .filter(UserLog.repository_id == repo)\ + journal = ( + UserLog.query() + .filter(UserLog.user_id == author) + .order_by(UserLog.user_log_id.asc()) + .filter(UserLog.repository_id == repo) .all() - assert journal[-1].action == 'repo.pull_request.close' + ) + assert journal[-1].action == "repo.pull_request.close" @pytest.mark.backends("git", "hg") def test_api_close_pull_request_already_closed_error(self, pr_util): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id pull_request_repo = pull_request.target_repo.repo_name - PullRequestModel().close_pull_request( - pull_request, pull_request.author) + PullRequestModel().close_pull_request(pull_request, pull_request.author) id_, params = build_data( - self.apikey, 'close_pull_request', - repoid=pull_request_repo, pullrequestid=pull_request_id) + self.apikey, "close_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id + ) response = api_call(self.app, params) - expected = 'pull request `%s` is already closed' % pull_request_id + expected = "pull request `%s` is already closed" % pull_request_id assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") def test_api_close_pull_request_repo_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'close_pull_request', - repoid=666, pullrequestid=pull_request.pull_request_id) + self.apikey, "close_pull_request", repoid=666, pullrequestid=pull_request.pull_request_id + ) response = api_call(self.app, params) - expected = 'repository `666` does not exist' + expected = "repository `666` does not exist" assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") - def test_api_close_pull_request_non_admin_with_userid_error(self, - pr_util): + def test_api_close_pull_request_non_admin_with_userid_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey_regular, 'close_pull_request', + self.apikey_regular, + "close_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - userid=TEST_USER_ADMIN_LOGIN) + userid=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") - def test_api_close_pull_request_no_perms_to_close( - self, user_util, pr_util): + def test_api_close_pull_request_no_perms_to_close(self, user_util, pr_util): user = user_util.create_user() pull_request = pr_util.create_pull_request() id_, params = build_data( - user.api_key, 'close_pull_request', + user.api_key, + "close_pull_request", repoid=pull_request.target_repo.repo_name, - pullrequestid=pull_request.pull_request_id,) + pullrequestid=pull_request.pull_request_id, + ) response = api_call(self.app, params) - expected = ('pull request `%s` close failed, ' - 'no permission to close.') % pull_request.pull_request_id + expected = ("pull request `%s` close failed, no permission to close.") % pull_request.pull_request_id - response_json = response.json['error'] + response_json = response.json["error"] assert response_json == expected diff --git a/rhodecode/api/tests/test_comment_commit.py b/rhodecode/api/tests/test_comment_commit.py index 8c247bb9..11585656 100644 --- a/rhodecode/api/tests/test_comment_commit.py +++ b/rhodecode/api/tests/test_comment_commit.py @@ -19,8 +19,7 @@ import pytest from rhodecode.model.db import ChangesetStatus, User -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") @@ -28,59 +27,74 @@ class TestCommentCommit(object): def test_api_comment_commit_on_empty_repo(self, backend): repo = backend.create_repo() id_, params = build_data( - self.apikey, 'comment_commit', repoid=repo.repo_name, - commit_id='tip', message='message', status_change=None) + self.apikey, "comment_commit", repoid=repo.repo_name, commit_id="tip", message="message", status_change=None + ) response = api_call(self.app, params) - expected = 'There are no commits yet' + expected = "There are no commits yet" assert_error(id_, expected, given=response.body) - @pytest.mark.parametrize("commit_id, expected_err", [ - ('abcabca', {'hg': 'Commit {commit} does not exist for `{repo}`', - 'git': 'Commit {commit} does not exist for `{repo}`', - 'svn': 'Commit id {commit} not understood.'}), - ('idontexist', {'hg': 'Commit {commit} does not exist for `{repo}`', - 'git': 'Commit {commit} does not exist for `{repo}`', - 'svn': 'Commit id {commit} not understood.'}), - ]) + @pytest.mark.parametrize( + "commit_id, expected_err", + [ + ( + "abcabca", + { + "hg": "Commit {commit} does not exist for `{repo}`", + "git": "Commit {commit} does not exist for `{repo}`", + "svn": "Commit id {commit} not understood.", + }, + ), + ( + "idontexist", + { + "hg": "Commit {commit} does not exist for `{repo}`", + "git": "Commit {commit} does not exist for `{repo}`", + "svn": "Commit id {commit} not understood.", + }, + ), + ], + ) def test_api_comment_commit_wrong_hash(self, backend, commit_id, expected_err): repo_name = backend.repo.repo_name id_, params = build_data( - self.apikey, 'comment_commit', repoid=repo_name, - commit_id=commit_id, message='message', status_change=None) + self.apikey, "comment_commit", repoid=repo_name, commit_id=commit_id, message="message", status_change=None + ) response = api_call(self.app, params) expected_err = expected_err[backend.alias] - expected_err = expected_err.format( - repo=backend.repo.scm_instance().name, commit=commit_id) + expected_err = expected_err.format(repo=backend.repo.scm_instance().name, commit=commit_id) assert_error(id_, expected_err, given=response.body) - @pytest.mark.parametrize("status_change, message, commit_id", [ - (None, 'Hallo', 'tip'), - (ChangesetStatus.STATUS_APPROVED, 'Approved', 'tip'), - (ChangesetStatus.STATUS_REJECTED, 'Rejected', 'tip'), - ]) - def test_api_comment_commit( - self, backend, status_change, message, commit_id, - no_notifications): - + @pytest.mark.parametrize( + "status_change, message, commit_id", + [ + (None, "Hallo", "tip"), + (ChangesetStatus.STATUS_APPROVED, "Approved", "tip"), + (ChangesetStatus.STATUS_REJECTED, "Rejected", "tip"), + ], + ) + def test_api_comment_commit(self, backend, status_change, message, commit_id, no_notifications): commit_id = backend.repo.scm_instance().get_commit(commit_id).raw_id id_, params = build_data( - self.apikey, 'comment_commit', repoid=backend.repo_name, - commit_id=commit_id, message=message, status=status_change) + self.apikey, + "comment_commit", + repoid=backend.repo_name, + commit_id=commit_id, + message=message, + status=status_change, + ) response = api_call(self.app, params) repo = backend.repo.scm_instance() expected = { - 'msg': 'Commented on commit `%s` for repository `%s`' % ( - repo.get_commit().raw_id, backend.repo_name), - 'status_change': status_change, - 'success': True + "msg": "Commented on commit `%s` for repository `%s`" % (repo.get_commit().raw_id, backend.repo_name), + "status_change": status_change, + "success": True, } assert_ok(id_, expected, given=response.body) def test_api_comment_commit_with_extra_recipients(self, backend, user_util): - - commit_id = backend.repo.scm_instance().get_commit('tip').raw_id + commit_id = backend.repo.scm_instance().get_commit("tip").raw_id user1 = user_util.create_user() user1_id = user1.user_id @@ -88,27 +102,29 @@ class TestCommentCommit(object): user2_id = user2.user_id id_, params = build_data( - self.apikey, 'comment_commit', repoid=backend.repo_name, + self.apikey, + "comment_commit", + repoid=backend.repo_name, commit_id=commit_id, - message='abracadabra', - extra_recipients=[user1.user_id, user2.username]) + message="abracadabra", + extra_recipients=[user1.user_id, user2.username], + ) response = api_call(self.app, params) repo = backend.repo.scm_instance() expected = { - 'msg': 'Commented on commit `%s` for repository `%s`' % ( - repo.get_commit().raw_id, backend.repo_name), - 'status_change': None, - 'success': True + "msg": "Commented on commit `%s` for repository `%s`" % (repo.get_commit().raw_id, backend.repo_name), + "status_change": None, + "success": True, } assert_ok(id_, expected, given=response.body) # check user1/user2 inbox for notification user1 = User.get(user1_id) assert 1 == len(user1.notifications) - assert 'abracadabra' in user1.notifications[0].notification.body + assert "abracadabra" in user1.notifications[0].notification.body user2 = User.get(user2_id) assert 1 == len(user2.notifications) - assert 'abracadabra' in user2.notifications[0].notification.body + assert "abracadabra" in user2.notifications[0].notification.body diff --git a/rhodecode/api/tests/test_comment_pull_request.py b/rhodecode/api/tests/test_comment_pull_request.py index b0100489..ba68a0d3 100644 --- a/rhodecode/api/tests/test_comment_pull_request.py +++ b/rhodecode/api/tests/test_comment_pull_request.py @@ -22,8 +22,7 @@ from rhodecode.model.comment import CommentsModel from rhodecode.model.db import UserLog, User, ChangesetComment from rhodecode.model.pull_request import PullRequestModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") @@ -43,29 +42,32 @@ class TestCommentPullRequest(object): author = pull_request.user_id repo = pull_request.target_repo.repo_id id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - message='test message') + message="test message", + ) response = api_call(self.app, params) pull_request = PullRequestModel().get(pull_request.pull_request_id) - comments = CommentsModel().get_comments( - pull_request.target_repo.repo_id, pull_request=pull_request) + comments = CommentsModel().get_comments(pull_request.target_repo.repo_id, pull_request=pull_request) expected = { - 'pull_request_id': pull_request.pull_request_id, - 'comment_id': comments[-1].comment_id, - 'status': {'given': None, 'was_changed': None} + "pull_request_id": pull_request.pull_request_id, + "comment_id": comments[-1].comment_id, + "status": {"given": None, "was_changed": None}, } assert_ok(id_, expected, response.body) - journal = UserLog.query()\ - .filter(UserLog.user_id == author)\ - .filter(UserLog.repository_id == repo) \ - .order_by(UserLog.user_log_id.asc()) \ + journal = ( + UserLog.query() + .filter(UserLog.user_id == author) + .filter(UserLog.repository_id == repo) + .order_by(UserLog.user_log_id.asc()) .all() - assert journal[-1].action == 'repo.pull_request.comment.create' + ) + assert journal[-1].action == "repo.pull_request.comment.create" @pytest.mark.backends("git", "hg") def test_api_comment_pull_request_with_extra_recipients(self, pr_util, user_util): @@ -77,105 +79,109 @@ class TestCommentPullRequest(object): user2_id = user2.user_id id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - message='test message', - extra_recipients=[user1.user_id, user2.username] + message="test message", + extra_recipients=[user1.user_id, user2.username], ) response = api_call(self.app, params) pull_request = PullRequestModel().get(pull_request.pull_request_id) - comments = CommentsModel().get_comments( - pull_request.target_repo.repo_id, pull_request=pull_request) + comments = CommentsModel().get_comments(pull_request.target_repo.repo_id, pull_request=pull_request) expected = { - 'pull_request_id': pull_request.pull_request_id, - 'comment_id': comments[-1].comment_id, - 'status': {'given': None, 'was_changed': None} + "pull_request_id": pull_request.pull_request_id, + "comment_id": comments[-1].comment_id, + "status": {"given": None, "was_changed": None}, } assert_ok(id_, expected, response.body) # check user1/user2 inbox for notification user1 = User.get(user1_id) assert 1 == len(user1.notifications) - assert 'test message' in user1.notifications[0].notification.body + assert "test message" in user1.notifications[0].notification.body user2 = User.get(user2_id) assert 1 == len(user2.notifications) - assert 'test message' in user2.notifications[0].notification.body + assert "test message" in user2.notifications[0].notification.body @pytest.mark.backends("git", "hg") - def test_api_comment_pull_request_change_status( - self, pr_util, no_notifications): + def test_api_comment_pull_request_change_status(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - status='rejected') + status="rejected", + ) response = api_call(self.app, params) pull_request = PullRequestModel().get(pull_request_id) - comments = CommentsModel().get_comments( - pull_request.target_repo.repo_id, pull_request=pull_request) + comments = CommentsModel().get_comments(pull_request.target_repo.repo_id, pull_request=pull_request) expected = { - 'pull_request_id': pull_request.pull_request_id, - 'comment_id': comments[-1].comment_id, - 'status': {'given': 'rejected', 'was_changed': True} + "pull_request_id": pull_request.pull_request_id, + "comment_id": comments[-1].comment_id, + "status": {"given": "rejected", "was_changed": True}, } assert_ok(id_, expected, response.body) @pytest.mark.backends("git", "hg") def test_api_comment_pull_request_change_status_with_specific_commit_id_and_test_commit( - self, pr_util, no_notifications): + self, pr_util, no_notifications + ): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id - latest_commit_id = 'test_commit' + latest_commit_id = "test_commit" # inject additional revision, to fail test the status change on # non-latest commit - pull_request.revisions = pull_request.revisions + ['test_commit'] + pull_request.revisions = pull_request.revisions + ["test_commit"] id_, params = build_data( - self.apikey, 'comment_pull_request', - message='test-change-of-status-not-allowed', + self.apikey, + "comment_pull_request", + message="test-change-of-status-not-allowed", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - status='approved', commit_id=latest_commit_id) + status="approved", + commit_id=latest_commit_id, + ) response = api_call(self.app, params) pull_request = PullRequestModel().get(pull_request_id) - comments = CommentsModel().get_comments( - pull_request.target_repo.repo_id, pull_request=pull_request) + comments = CommentsModel().get_comments(pull_request.target_repo.repo_id, pull_request=pull_request) expected = { - 'pull_request_id': pull_request.pull_request_id, - 'comment_id': comments[-1].comment_id, - 'status': {'given': 'approved', 'was_changed': False} + "pull_request_id": pull_request.pull_request_id, + "comment_id": comments[-1].comment_id, + "status": {"given": "approved", "was_changed": False}, } assert_ok(id_, expected, response.body) @pytest.mark.backends("git", "hg") - def test_api_comment_pull_request_change_status_with_specific_commit_id( - self, pr_util, no_notifications): + def test_api_comment_pull_request_change_status_with_specific_commit_id(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id latest_commit_id = pull_request.revisions[0] id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - status='approved', commit_id=latest_commit_id) + status="approved", + commit_id=latest_commit_id, + ) response = api_call(self.app, params) pull_request = PullRequestModel().get(pull_request_id) - comments = CommentsModel().get_comments( - pull_request.target_repo.repo_id, pull_request=pull_request) + comments = CommentsModel().get_comments(pull_request.target_repo.repo_id, pull_request=pull_request) expected = { - 'pull_request_id': pull_request.pull_request_id, - 'comment_id': comments[-1].comment_id, - 'status': {'given': 'approved', 'was_changed': True} + "pull_request_id": pull_request.pull_request_id, + "comment_id": comments[-1].comment_id, + "status": {"given": "approved", "was_changed": True}, } assert_ok(id_, expected, response.body) @@ -185,12 +191,11 @@ class TestCommentPullRequest(object): pull_request_id = pull_request.pull_request_id pull_request_repo = pull_request.target_repo.repo_name id_, params = build_data( - self.apikey, 'comment_pull_request', - repoid=pull_request_repo, - pullrequestid=pull_request_id) + self.apikey, "comment_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id + ) response = api_call(self.app, params) - expected = 'Both message and status parameters are missing. At least one is required.' + expected = "Both message and status parameters are missing. At least one is required." assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") @@ -199,51 +204,53 @@ class TestCommentPullRequest(object): pull_request_id = pull_request.pull_request_id pull_request_repo = pull_request.target_repo.repo_name id_, params = build_data( - self.apikey, 'comment_pull_request', - repoid=pull_request_repo, - pullrequestid=pull_request_id, - status='42') + self.apikey, "comment_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id, status="42" + ) response = api_call(self.app, params) - expected = 'Unknown comment status: `42`' + expected = "Unknown comment status: `42`" assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") def test_api_comment_pull_request_repo_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'comment_pull_request', - repoid=666, pullrequestid=pull_request.pull_request_id) + self.apikey, "comment_pull_request", repoid=666, pullrequestid=pull_request.pull_request_id + ) response = api_call(self.app, params) - expected = 'repository `666` does not exist' + expected = "repository `666` does not exist" assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") def test_api_comment_pull_request_non_admin_with_userid_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey_regular, 'comment_pull_request', + self.apikey_regular, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - userid=TEST_USER_ADMIN_LOGIN) + userid=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") def test_api_comment_pull_request_wrong_commit_id_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey_regular, 'comment_pull_request', + self.apikey_regular, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, - status='approved', + status="approved", pullrequestid=pull_request.pull_request_id, - commit_id='XXX') + commit_id="XXX", + ) response = api_call(self.app, params) - expected = 'Invalid commit_id `XXX` for this pull request.' + expected = "Invalid commit_id `XXX` for this pull request." assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") @@ -252,26 +259,26 @@ class TestCommentPullRequest(object): id_, params = build_data( self.apikey, - 'comment_pull_request', + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - message='test message', + message="test message", ) response = api_call(self.app, params) json_response = response.json - comment_id = json_response['result']['comment_id'] + comment_id = json_response["result"]["comment_id"] - message_after_edit = 'just message' + message_after_edit = "just message" id_, params = build_data( self.apikey, - 'edit_comment', + "edit_comment", comment_id=comment_id, message=message_after_edit, version=0, ) response = api_call(self.app, params) json_response = response.json - assert json_response['result']['version'] == 1 + assert json_response["result"]["version"] == 1 text_form_db = ChangesetComment.get(comment_id).text assert message_after_edit == text_form_db @@ -281,24 +288,26 @@ class TestCommentPullRequest(object): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - message='test message') + message="test message", + ) response = api_call(self.app, params) json_response = response.json - comment_id = json_response['result']['comment_id'] + comment_id = json_response["result"]["comment_id"] - message_after_edit = 'just message' + message_after_edit = "just message" id_, params = build_data( self.apikey, - 'edit_comment', + "edit_comment", comment_id=comment_id, message=message_after_edit, version=1, ) response = api_call(self.app, params) - expected = 'comment ({}) version ({}) mismatch'.format(comment_id, 1) + expected = "comment ({}) version ({}) mismatch".format(comment_id, 1) assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") @@ -306,19 +315,21 @@ class TestCommentPullRequest(object): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - message='test message') + message="test message", + ) response = api_call(self.app, params) json_response = response.json - comment_id = json_response['result']['comment_id'] + comment_id = json_response["result"]["comment_id"] id_, params = build_data( self.apikey, - 'edit_comment', + "edit_comment", comment_id=comment_id, - message='', + message="", version=0, ) response = api_call(self.app, params) @@ -331,25 +342,25 @@ class TestCommentPullRequest(object): pull_request_id = pull_request.pull_request_id id_, params = build_data( self.apikey, - 'comment_pull_request', + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request_id, - message='test message' + message="test message", ) response = api_call(self.app, params) json_response = response.json - comment_id = json_response['result']['comment_id'] + comment_id = json_response["result"]["comment_id"] id_, params = build_data( self.apikey_regular, - 'edit_comment', + "edit_comment", comment_id=comment_id, - message='just message', + message="just message", version=0, - userid=TEST_USER_ADMIN_LOGIN + userid=TEST_USER_ADMIN_LOGIN, ) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") @@ -358,20 +369,20 @@ class TestCommentPullRequest(object): pull_request_id = pull_request.pull_request_id id_, params = build_data( self.apikey, - 'comment_pull_request', + "comment_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request_id, - message='test message' + message="test message", ) response = api_call(self.app, params) json_response = response.json - comment_id = json_response['result']['comment_id'] + comment_id = json_response["result"]["comment_id"] id_, params = build_data( self.apikey_regular, - 'edit_comment', + "edit_comment", comment_id=comment_id, - message='just message', + message="just message", version=0, ) response = api_call(self.app, params) diff --git a/rhodecode/api/tests/test_create_gist.py b/rhodecode/api/tests/test_create_gist.py index dfffe161..5ce1d036 100644 --- a/rhodecode/api/tests/test_create_gist.py +++ b/rhodecode/api/tests/test_create_gist.py @@ -21,70 +21,85 @@ import pytest from rhodecode.model.db import Gist from rhodecode.model.gist import GistModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash from rhodecode.tests.fixtures.rc_fixture import Fixture @pytest.mark.usefixtures("testuser_api", "app") class TestApiCreateGist(object): - @pytest.mark.parametrize("lifetime, gist_type, gist_acl_level", [ - (10, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC), - (20, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PRIVATE), - (40, Gist.GIST_PRIVATE, Gist.ACL_LEVEL_PUBLIC), - (80, Gist.GIST_PRIVATE, Gist.ACL_LEVEL_PRIVATE), - ]) + @pytest.mark.parametrize( + "lifetime, gist_type, gist_acl_level", + [ + (10, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC), + (20, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PRIVATE), + (40, Gist.GIST_PRIVATE, Gist.ACL_LEVEL_PUBLIC), + (80, Gist.GIST_PRIVATE, Gist.ACL_LEVEL_PRIVATE), + ], + ) def test_api_create_gist(self, lifetime, gist_type, gist_acl_level): id_, params = build_data( - self.apikey_regular, 'create_gist', + self.apikey_regular, + "create_gist", lifetime=lifetime, - description='foobar-gist', + description="foobar-gist", gist_type=gist_type, acl_level=gist_acl_level, - files={'foobar_ąć': {'content': 'foo'}}) + files={"foobar_ąć": {"content": "foo"}}, + ) response = api_call(self.app, params) response_json = response.json - gist = response_json['result']['gist'] + gist = response_json["result"]["gist"] expected = { - 'gist': { - 'access_id': gist['access_id'], - 'created_on': gist['created_on'], - 'modified_at': gist['modified_at'], - 'description': 'foobar-gist', - 'expires': gist['expires'], - 'gist_id': gist['gist_id'], - 'type': gist_type, - 'url': gist['url'], + "gist": { + "access_id": gist["access_id"], + "created_on": gist["created_on"], + "modified_at": gist["modified_at"], + "description": "foobar-gist", + "expires": gist["expires"], + "gist_id": gist["gist_id"], + "type": gist_type, + "url": gist["url"], # content is empty since we don't show it here - 'content': None, - 'acl_level': gist_acl_level, + "content": None, + "acl_level": gist_acl_level, }, - 'msg': 'created new gist' + "msg": "created new gist", } try: assert_ok(id_, expected, given=response.body) finally: Fixture().destroy_gists() - @pytest.mark.parametrize("expected, lifetime, gist_type, gist_acl_level, files", [ - ({'gist_type': '"ups" is not one of private, public'}, - 10, 'ups', Gist.ACL_LEVEL_PUBLIC, {'f': {'content': 'f'}}), - - ({'lifetime': '-120 is less than minimum value -1'}, - -120, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC, {'f': {'content': 'f'}}), - - ({'0.content': 'Required'}, - 10, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC, {'f': {'x': 'f'}}), - ]) - def test_api_try_create_gist( - self, expected, lifetime, gist_type, gist_acl_level, files): + @pytest.mark.parametrize( + "expected, lifetime, gist_type, gist_acl_level, files", + [ + ( + {"gist_type": '"ups" is not one of private, public'}, + 10, + "ups", + Gist.ACL_LEVEL_PUBLIC, + {"f": {"content": "f"}}, + ), + ( + {"lifetime": "-120 is less than minimum value -1"}, + -120, + Gist.GIST_PUBLIC, + Gist.ACL_LEVEL_PUBLIC, + {"f": {"content": "f"}}, + ), + ({"0.content": "Required"}, 10, Gist.GIST_PUBLIC, Gist.ACL_LEVEL_PUBLIC, {"f": {"x": "f"}}), + ], + ) + def test_api_try_create_gist(self, expected, lifetime, gist_type, gist_acl_level, files): id_, params = build_data( - self.apikey_regular, 'create_gist', + self.apikey_regular, + "create_gist", lifetime=lifetime, - description='foobar-gist', + description="foobar-gist", gist_type=gist_type, acl_level=gist_acl_level, - files=files) + files=files, + ) response = api_call(self.app, params) try: @@ -92,9 +107,9 @@ class TestApiCreateGist(object): finally: Fixture().destroy_gists() - @mock.patch.object(GistModel, 'create', crash) + @mock.patch.object(GistModel, "create", crash) def test_api_create_gist_exception_occurred(self): - id_, params = build_data(self.apikey_regular, 'create_gist', files={}) + id_, params = build_data(self.apikey_regular, "create_gist", files={}) response = api_call(self.app, params) - expected = 'failed to create gist' + expected = "failed to create gist" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_create_pull_request.py b/rhodecode/api/tests/test_create_pull_request.py index e1ca2d3e..aa138087 100644 --- a/rhodecode/api/tests/test_create_pull_request.py +++ b/rhodecode/api/tests/test_create_pull_request.py @@ -38,223 +38,197 @@ class TestCreatePullRequestApi(object): def test_create_with_wrong_data(self): required_data = { - 'source_repo': 'tests/source_repo', - 'target_repo': 'tests/target_repo', - 'source_ref': 'branch:default:initial', - 'target_ref': 'branch:default:new-feature', + "source_repo": "tests/source_repo", + "target_repo": "tests/target_repo", + "source_ref": "branch:default:initial", + "target_ref": "branch:default:new-feature", } for key in required_data: data = required_data.copy() data.pop(key) - id_, params = build_data( - self.apikey, 'create_pull_request', **data) + id_, params = build_data(self.apikey, "create_pull_request", **data) response = api_call(self.app, params) - expected = 'Missing non optional `{}` arg in JSON DATA'.format(key) + expected = "Missing non optional `{}` arg in JSON DATA".format(key) assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") - @pytest.mark.parametrize('source_ref', [ - 'bookmarg:default:initial' - ]) + @pytest.mark.parametrize("source_ref", ["bookmarg:default:initial"]) def test_create_with_wrong_refs_data(self, backend, source_ref): - data = self._prepare_data(backend) - data['source_ref'] = source_ref + data["source_ref"] = source_ref - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected = "Ref `{}` type is not allowed. " \ - "Only:['bookmark', 'book', 'tag', 'branch'] " \ - "are possible.".format(source_ref) + expected = "Ref `{}` type is not allowed. Only:['bookmark', 'book', 'tag', 'branch'] are possible.".format( + source_ref + ) assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") def test_create_with_correct_data(self, backend): data = self._prepare_data(backend) - RepoModel().revoke_user_permission( - self.source.repo_name, User.DEFAULT_USER) - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + RepoModel().revoke_user_permission(self.source.repo_name, User.DEFAULT_USER) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = "Created new pull request `{title}`".format( - title=data['title']) + expected_message = "Created new pull request `{title}`".format(title=data["title"]) result = response.json - assert result['error'] is None - assert result['result']['msg'] == expected_message - pull_request_id = result['result']['pull_request_id'] + assert result["error"] is None + assert result["result"]["msg"] == expected_message + pull_request_id = result["result"]["pull_request_id"] pull_request = PullRequestModel().get(pull_request_id) - assert pull_request.title == data['title'] - assert pull_request.description == data['description'] - assert pull_request.source_ref == data['source_ref'] - assert pull_request.target_ref == data['target_ref'] - assert pull_request.source_repo.repo_name == data['source_repo'] - assert pull_request.target_repo.repo_name == data['target_repo'] - assert pull_request.revisions == [self.commit_ids['change']] + assert pull_request.title == data["title"] + assert pull_request.description == data["description"] + assert pull_request.source_ref == data["source_ref"] + assert pull_request.target_ref == data["target_ref"] + assert pull_request.source_repo.repo_name == data["source_repo"] + assert pull_request.target_repo.repo_name == data["target_repo"] + assert pull_request.revisions == [self.commit_ids["change"]] assert len(pull_request.reviewers) == 1 @pytest.mark.backends("git", "hg") def test_create_with_empty_description(self, backend): data = self._prepare_data(backend) - data.pop('description') - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + data.pop("description") + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = "Created new pull request `{title}`".format( - title=data['title']) + expected_message = "Created new pull request `{title}`".format(title=data["title"]) result = response.json - assert result['error'] is None - assert result['result']['msg'] == expected_message - pull_request_id = result['result']['pull_request_id'] + assert result["error"] is None + assert result["result"]["msg"] == expected_message + pull_request_id = result["result"]["pull_request_id"] pull_request = PullRequestModel().get(pull_request_id) - assert pull_request.description == '' + assert pull_request.description == "" @pytest.mark.backends("git", "hg") def test_create_with_empty_title(self, backend): data = self._prepare_data(backend) - data.pop('title') - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + data.pop("title") + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) result = response.json - pull_request_id = result['result']['pull_request_id'] + pull_request_id = result["result"]["pull_request_id"] pull_request = PullRequestModel().get(pull_request_id) - data['ref'] = backend.default_branch_name - title = '{source_repo}#{ref} to {target_repo}'.format(**data) + data["ref"] = backend.default_branch_name + title = "{source_repo}#{ref} to {target_repo}".format(**data) assert pull_request.title == title @pytest.mark.backends("git", "hg") - def test_create_with_reviewers_specified_by_names( - self, backend, no_notifications): + def test_create_with_reviewers_specified_by_names(self, backend, no_notifications): data = self._prepare_data(backend) reviewers = [ - {'username': TEST_USER_REGULAR_LOGIN, - 'reasons': ['{} added manually'.format(TEST_USER_REGULAR_LOGIN)]}, - {'username': TEST_USER_ADMIN_LOGIN, - 'reasons': ['{} added manually'.format(TEST_USER_ADMIN_LOGIN)], - 'mandatory': True}, + {"username": TEST_USER_REGULAR_LOGIN, "reasons": ["{} added manually".format(TEST_USER_REGULAR_LOGIN)]}, + { + "username": TEST_USER_ADMIN_LOGIN, + "reasons": ["{} added manually".format(TEST_USER_ADMIN_LOGIN)], + "mandatory": True, + }, ] - data['reviewers'] = reviewers + data["reviewers"] = reviewers - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = "Created new pull request `{title}`".format( - title=data['title']) + expected_message = "Created new pull request `{title}`".format(title=data["title"]) result = response.json - assert result['error'] is None - assert result['result']['msg'] == expected_message - pull_request_id = result['result']['pull_request_id'] + assert result["error"] is None + assert result["result"]["msg"] == expected_message + pull_request_id = result["result"]["pull_request_id"] pull_request = PullRequestModel().get(pull_request_id) actual_reviewers = [] for rev in pull_request.reviewers: entry = { - 'username': rev.user.username, - 'reasons': rev.reasons, - } + "username": rev.user.username, + "reasons": rev.reasons, + } if rev.mandatory: - entry['mandatory'] = rev.mandatory + entry["mandatory"] = rev.mandatory actual_reviewers.append(entry) owner_username = pull_request.target_repo.user.username for spec_reviewer in reviewers[::]: # default reviewer will be added who is an owner of the repo # this get's overridden by a add owner to reviewers rule - if spec_reviewer['username'] == owner_username: - spec_reviewer['reasons'] = [u'Default reviewer', u'Repository owner'] + if spec_reviewer["username"] == owner_username: + spec_reviewer["reasons"] = ["Default reviewer", "Repository owner"] # since owner is more important, we don't inherit mandatory flag - del spec_reviewer['mandatory'] + del spec_reviewer["mandatory"] - assert sorted(actual_reviewers, key=lambda e: e['username']) \ - == sorted(reviewers, key=lambda e: e['username']) + assert sorted(actual_reviewers, key=lambda e: e["username"]) == sorted(reviewers, key=lambda e: e["username"]) @pytest.mark.backends("git", "hg") - def test_create_with_reviewers_specified_by_ids( - self, backend, no_notifications): + def test_create_with_reviewers_specified_by_ids(self, backend, no_notifications): data = self._prepare_data(backend) reviewers = [ - {'username': UserModel().get_by_username( - TEST_USER_REGULAR_LOGIN).user_id, - 'reasons': ['added manually']}, - {'username': UserModel().get_by_username( - TEST_USER_ADMIN_LOGIN).user_id, - 'reasons': ['added manually']}, + {"username": UserModel().get_by_username(TEST_USER_REGULAR_LOGIN).user_id, "reasons": ["added manually"]}, + {"username": UserModel().get_by_username(TEST_USER_ADMIN_LOGIN).user_id, "reasons": ["added manually"]}, ] - data['reviewers'] = reviewers - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + data["reviewers"] = reviewers + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = "Created new pull request `{title}`".format( - title=data['title']) + expected_message = "Created new pull request `{title}`".format(title=data["title"]) result = response.json - assert result['error'] is None - assert result['result']['msg'] == expected_message - pull_request_id = result['result']['pull_request_id'] + assert result["error"] is None + assert result["result"]["msg"] == expected_message + pull_request_id = result["result"]["pull_request_id"] pull_request = PullRequestModel().get(pull_request_id) actual_reviewers = [] for rev in pull_request.reviewers: entry = { - 'username': rev.user.user_id, - 'reasons': rev.reasons, - } + "username": rev.user.user_id, + "reasons": rev.reasons, + } if rev.mandatory: - entry['mandatory'] = rev.mandatory + entry["mandatory"] = rev.mandatory actual_reviewers.append(entry) owner_user_id = pull_request.target_repo.user.user_id for spec_reviewer in reviewers[::]: # default reviewer will be added who is an owner of the repo # this get's overridden by a add owner to reviewers rule - if spec_reviewer['username'] == owner_user_id: - spec_reviewer['reasons'] = [u'Default reviewer', u'Repository owner'] + if spec_reviewer["username"] == owner_user_id: + spec_reviewer["reasons"] = ["Default reviewer", "Repository owner"] - assert sorted(actual_reviewers, key=lambda e: e['username']) \ - == sorted(reviewers, key=lambda e: e['username']) + assert sorted(actual_reviewers, key=lambda e: e["username"]) == sorted(reviewers, key=lambda e: e["username"]) @pytest.mark.backends("git", "hg") def test_create_fails_when_the_reviewer_is_not_found(self, backend): data = self._prepare_data(backend) - data['reviewers'] = [{'username': 'somebody'}] - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + data["reviewers"] = [{"username": "somebody"}] + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = 'user `somebody` does not exist' + expected_message = "user `somebody` does not exist" assert_error(id_, expected_message, given=response.body) @pytest.mark.backends("git", "hg") def test_cannot_create_with_reviewers_in_wrong_format(self, backend): data = self._prepare_data(backend) - reviewers = ','.join([TEST_USER_REGULAR_LOGIN, TEST_USER_ADMIN_LOGIN]) - data['reviewers'] = reviewers - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + reviewers = ",".join([TEST_USER_REGULAR_LOGIN, TEST_USER_ADMIN_LOGIN]) + data["reviewers"] = reviewers + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = {u'': '"test_regular,test_admin" is not iterable'} + expected_message = {"": '"test_regular,test_admin" is not iterable'} assert_error(id_, expected_message, given=response.body) @pytest.mark.backends("git", "hg") def test_create_with_no_commit_hashes(self, backend): data = self._prepare_data(backend) - expected_source_ref = data['source_ref'] - expected_target_ref = data['target_ref'] - data['source_ref'] = 'branch:{}'.format(backend.default_branch_name) - data['target_ref'] = 'branch:{}'.format(backend.default_branch_name) - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + expected_source_ref = data["source_ref"] + expected_target_ref = data["target_ref"] + data["source_ref"] = "branch:{}".format(backend.default_branch_name) + data["target_ref"] = "branch:{}".format(backend.default_branch_name) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = "Created new pull request `{title}`".format( - title=data['title']) + expected_message = "Created new pull request `{title}`".format(title=data["title"]) result = response.json - assert result['result']['msg'] == expected_message - pull_request_id = result['result']['pull_request_id'] + assert result["result"]["msg"] == expected_message + pull_request_id = result["result"]["pull_request_id"] pull_request = PullRequestModel().get(pull_request_id) assert pull_request.source_ref == expected_source_ref assert pull_request.target_ref == expected_target_ref @@ -262,105 +236,91 @@ class TestCreatePullRequestApi(object): @pytest.mark.backends("git", "hg") @pytest.mark.parametrize("data_key", ["source_repo", "target_repo"]) def test_create_fails_with_wrong_repo(self, backend, data_key): - repo_name = 'fake-repo' + repo_name = "fake-repo" data = self._prepare_data(backend) data[data_key] = repo_name - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = 'repository `{}` does not exist'.format(repo_name) + expected_message = "repository `{}` does not exist".format(repo_name) assert_error(id_, expected_message, given=response.body) @pytest.mark.backends("git", "hg") @pytest.mark.parametrize("data_key", ["source_ref", "target_ref"]) def test_create_fails_with_non_existing_branch(self, backend, data_key): - branch_name = 'test-branch' + branch_name = "test-branch" data = self._prepare_data(backend) data[data_key] = "branch:{}".format(branch_name) - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = 'The specified value:{type}:`{name}` ' \ - 'does not exist, or is not allowed.'.format(type='branch', - name=branch_name) + expected_message = "The specified value:{type}:`{name}` does not exist, or is not allowed.".format( + type="branch", name=branch_name + ) assert_error(id_, expected_message, given=response.body) @pytest.mark.backends("git", "hg") @pytest.mark.parametrize("data_key", ["source_ref", "target_ref"]) def test_create_fails_with_ref_in_a_wrong_format(self, backend, data_key): data = self._prepare_data(backend) - ref = 'stange-ref' + ref = "stange-ref" data[data_key] = ref - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) expected_message = ( - 'Ref `{ref}` given in a wrong format. Please check the API' - ' documentation for more details'.format(ref=ref)) + "Ref `{ref}` given in a wrong format. Please check the API documentation for more details".format(ref=ref) + ) assert_error(id_, expected_message, given=response.body) @pytest.mark.backends("git", "hg") @pytest.mark.parametrize("data_key", ["source_ref", "target_ref"]) def test_create_fails_with_non_existing_ref(self, backend, data_key): - commit_id = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10' + commit_id = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10" ref = self._get_full_ref(backend, commit_id) data = self._prepare_data(backend) data[data_key] = ref - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = 'Ref `{}` does not exist'.format(ref) + expected_message = "Ref `{}` does not exist".format(ref) assert_error(id_, expected_message, given=response.body) @pytest.mark.backends("git", "hg") def test_create_fails_when_no_revisions(self, backend): - data = self._prepare_data(backend, source_head='initial') - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + data = self._prepare_data(backend, source_head="initial") + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = 'no commits found for merge between specified references' + expected_message = "no commits found for merge between specified references" assert_error(id_, expected_message, given=response.body) @pytest.mark.backends("git", "hg") def test_create_fails_when_no_permissions(self, backend): data = self._prepare_data(backend) - RepoModel().revoke_user_permission( - self.source.repo_name, self.test_user) - RepoModel().revoke_user_permission( - self.source.repo_name, User.DEFAULT_USER) + RepoModel().revoke_user_permission(self.source.repo_name, self.test_user) + RepoModel().revoke_user_permission(self.source.repo_name, User.DEFAULT_USER) - id_, params = build_data( - self.apikey_regular, 'create_pull_request', **data) + id_, params = build_data(self.apikey_regular, "create_pull_request", **data) response = api_call(self.app, params) - expected_message = 'repository `{}` does not exist'.format( - self.source.repo_name) + expected_message = "repository `{}` does not exist".format(self.source.repo_name) assert_error(id_, expected_message, given=response.body) - def _prepare_data( - self, backend, source_head='change', target_head='initial'): + def _prepare_data(self, backend, source_head="change", target_head="initial"): commits = [ - {'message': 'initial'}, - {'message': 'change'}, - {'message': 'new-feature', 'parents': ['initial'], 'branch': 'feature'}, + {"message": "initial"}, + {"message": "change"}, + {"message": "new-feature", "parents": ["initial"], "branch": "feature"}, ] self.commit_ids = backend.create_master_repo(commits) self.source = backend.create_repo(heads=[source_head]) self.target = backend.create_repo(heads=[target_head]) data = { - 'source_repo': self.source.repo_name, - 'target_repo': self.target.repo_name, - 'source_ref': self._get_full_ref( - backend, self.commit_ids[source_head]), - 'target_ref': self._get_full_ref( - backend, self.commit_ids[target_head]), - 'title': 'Test PR 1', - 'description': 'Test' + "source_repo": self.source.repo_name, + "target_repo": self.target.repo_name, + "source_ref": self._get_full_ref(backend, self.commit_ids[source_head]), + "target_ref": self._get_full_ref(backend, self.commit_ids[target_head]), + "title": "Test PR 1", + "description": "Test", } - RepoModel().grant_user_permission( - self.source.repo_name, self.TEST_USER_LOGIN, 'repository.read') + RepoModel().grant_user_permission(self.source.repo_name, self.TEST_USER_LOGIN, "repository.read") return data def _get_full_ref(self, backend, commit_id): - return 'branch:{branch}:{commit_id}'.format( - branch=backend.default_branch_name, commit_id=commit_id) + return "branch:{branch}:{commit_id}".format(branch=backend.default_branch_name, commit_id=commit_id) diff --git a/rhodecode/api/tests/test_create_repo.py b/rhodecode/api/tests/test_create_repo.py index c19fb60d..efd28955 100644 --- a/rhodecode/api/tests/test_create_repo.py +++ b/rhodecode/api/tests/test_create_repo.py @@ -24,8 +24,7 @@ from rhodecode.model.meta import Session from rhodecode.model.repo import RepoModel from rhodecode.model.user import UserModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.lib.ext_json import json from rhodecode.lib.str_utils import safe_str @@ -36,19 +35,20 @@ fixture = Fixture() @pytest.mark.usefixtures("testuser_api", "app") class TestCreateRepo(object): - - @pytest.mark.parametrize('given, expected_name, expected_exc', [ - ('api repo-1', 'api-repo-1', False), - ('api-repo 1-ąć', 'api-repo-1-ąć', False), - ('unicode-ąć', u'unicode-ąć', False), - ('some repo v1.2', 'some-repo-v1.2', False), - ('v2.0', 'v2.0', False), - ]) + @pytest.mark.parametrize( + "given, expected_name, expected_exc", + [ + ("api repo-1", "api-repo-1", False), + ("api-repo 1-ąć", "api-repo-1-ąć", False), + ("unicode-ąć", "unicode-ąć", False), + ("some repo v1.2", "some-repo-v1.2", False), + ("v2.0", "v2.0", False), + ], + ) def test_api_create_repo(self, backend, given, expected_name, expected_exc): - id_, params = build_data( self.apikey, - 'create_repo', + "create_repo", repo_name=given, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, @@ -56,9 +56,9 @@ class TestCreateRepo(object): response = api_call(self.app, params) ret = { - 'msg': 'Created new repository `%s`' % (expected_name,), - 'success': True, - 'task': None, + "msg": "Created new repository `%s`" % (expected_name,), + "success": True, + "task": None, } expected = ret assert_ok(id_, expected, given=response.body) @@ -66,38 +66,39 @@ class TestCreateRepo(object): repo = RepoModel().get_by_repo_name(safe_str(expected_name)) assert repo is not None - id_, params = build_data(self.apikey, 'get_repo', repoid=expected_name) + id_, params = build_data(self.apikey, "get_repo", repoid=expected_name) response = api_call(self.app, params) body = json.loads(response.body) - assert body['result']['enable_downloads'] is False - assert body['result']['enable_locking'] is False - assert body['result']['enable_statistics'] is False + assert body["result"]["enable_downloads"] is False + assert body["result"]["enable_locking"] is False + assert body["result"]["enable_statistics"] is False fixture.destroy_repo(safe_str(expected_name)) def test_api_create_restricted_repo_type(self, backend): - repo_name = 'api-repo-type-{0}'.format(backend.alias) + repo_name = "api-repo-type-{0}".format(backend.alias) id_, params = build_data( self.apikey, - 'create_repo', + "create_repo", repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, ) - git_backend = settings.BACKENDS['git'] - with mock.patch( - 'rhodecode.lib.vcs.settings.BACKENDS', {'git': git_backend}): + git_backend = settings.BACKENDS["git"] + with mock.patch("rhodecode.lib.vcs.settings.BACKENDS", {"git": git_backend}): response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) - if backend.alias == 'git': + if backend.alias == "git": assert repo is not None expected = { - 'msg': 'Created new repository `{0}`'.format(repo_name,), - 'success': True, - 'task': None, + "msg": "Created new repository `{0}`".format( + repo_name, + ), + "success": True, + "task": None, } assert_ok(id_, expected, given=response.body) else: @@ -106,16 +107,16 @@ class TestCreateRepo(object): fixture.destroy_repo(repo_name) def test_api_create_repo_with_booleans(self, backend): - repo_name = 'api-repo-2' + repo_name = "api-repo-2" id_, params = build_data( self.apikey, - 'create_repo', + "create_repo", repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, repo_type=backend.alias, enable_statistics=True, enable_locking=True, - enable_downloads=True + enable_downloads=True, ) response = api_call(self.app, params) @@ -123,43 +124,45 @@ class TestCreateRepo(object): assert repo is not None ret = { - 'msg': 'Created new repository `%s`' % (repo_name,), - 'success': True, - 'task': None, + "msg": "Created new repository `%s`" % (repo_name,), + "success": True, + "task": None, } expected = ret assert_ok(id_, expected, given=response.body) - id_, params = build_data(self.apikey, 'get_repo', repoid=repo_name) + id_, params = build_data(self.apikey, "get_repo", repoid=repo_name) response = api_call(self.app, params) body = json.loads(response.body) - assert body['result']['enable_downloads'] is True - assert body['result']['enable_locking'] is True - assert body['result']['enable_statistics'] is True + assert body["result"]["enable_downloads"] is True + assert body["result"]["enable_locking"] is True + assert body["result"]["enable_statistics"] is True fixture.destroy_repo(repo_name) def test_api_create_repo_in_group(self, backend): - repo_group_name = 'my_gr' + repo_group_name = "my_gr" # create the parent fixture.create_repo_group(repo_group_name) - repo_name = '%s/api-repo-gr' % (repo_group_name,) + repo_name = "%s/api-repo-gr" % (repo_group_name,) id_, params = build_data( - self.apikey, 'create_repo', + self.apikey, + "create_repo", repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, - repo_type=backend.alias,) + repo_type=backend.alias, + ) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) assert repo is not None assert repo.group is not None ret = { - 'msg': 'Created new repository `%s`' % (repo_name,), - 'success': True, - 'task': None, + "msg": "Created new repository `%s`" % (repo_name,), + "success": True, + "task": None, } expected = ret assert_ok(id_, expected, given=response.body) @@ -167,104 +170,87 @@ class TestCreateRepo(object): fixture.destroy_repo_group(repo_group_name) def test_create_repo_in_group_that_doesnt_exist(self, backend, user_util): - repo_group_name = 'fake_group' + repo_group_name = "fake_group" - repo_name = '%s/api-repo-gr' % (repo_group_name,) + repo_name = "%s/api-repo-gr" % (repo_group_name,) id_, params = build_data( - self.apikey, 'create_repo', + self.apikey, + "create_repo", repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, - repo_type=backend.alias,) + repo_type=backend.alias, + ) response = api_call(self.app, params) - expected = {'repo_group': 'Repository group `{}` does not exist'.format( - repo_group_name)} + expected = {"repo_group": "Repository group `{}` does not exist".format(repo_group_name)} assert_error(id_, expected, given=response.body) def test_api_create_repo_unknown_owner(self, backend): - repo_name = 'api-repo-2' - owner = 'i-dont-exist' - id_, params = build_data( - self.apikey, 'create_repo', - repo_name=repo_name, - owner=owner, - repo_type=backend.alias) + repo_name = "api-repo-2" + owner = "i-dont-exist" + id_, params = build_data(self.apikey, "create_repo", repo_name=repo_name, owner=owner, repo_type=backend.alias) response = api_call(self.app, params) - expected = 'user `%s` does not exist' % (owner,) + expected = "user `%s` does not exist" % (owner,) assert_error(id_, expected, given=response.body) def test_api_create_repo_dont_specify_owner(self, backend): - repo_name = 'api-repo-3' - id_, params = build_data( - self.apikey, 'create_repo', - repo_name=repo_name, - repo_type=backend.alias) + repo_name = "api-repo-3" + id_, params = build_data(self.apikey, "create_repo", repo_name=repo_name, repo_type=backend.alias) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) assert repo is not None ret = { - 'msg': 'Created new repository `%s`' % (repo_name,), - 'success': True, - 'task': None, + "msg": "Created new repository `%s`" % (repo_name,), + "success": True, + "task": None, } expected = ret assert_ok(id_, expected, given=response.body) fixture.destroy_repo(repo_name) def test_api_create_repo_by_non_admin(self, backend): - repo_name = 'api-repo-4' - id_, params = build_data( - self.apikey_regular, 'create_repo', - repo_name=repo_name, - repo_type=backend.alias) + repo_name = "api-repo-4" + id_, params = build_data(self.apikey_regular, "create_repo", repo_name=repo_name, repo_type=backend.alias) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(repo_name) assert repo is not None ret = { - 'msg': 'Created new repository `%s`' % (repo_name,), - 'success': True, - 'task': None, + "msg": "Created new repository `%s`" % (repo_name,), + "success": True, + "task": None, } expected = ret assert_ok(id_, expected, given=response.body) fixture.destroy_repo(repo_name) def test_api_create_repo_by_non_admin_specify_owner(self, backend): - repo_name = 'api-repo-5' - owner = 'i-dont-exist' + repo_name = "api-repo-5" + owner = "i-dont-exist" id_, params = build_data( - self.apikey_regular, 'create_repo', - repo_name=repo_name, - repo_type=backend.alias, - owner=owner) + self.apikey_regular, "create_repo", repo_name=repo_name, repo_type=backend.alias, owner=owner + ) response = api_call(self.app, params) - expected = 'Only RhodeCode super-admin can specify `owner` param' + expected = "Only RhodeCode super-admin can specify `owner` param" assert_error(id_, expected, given=response.body) fixture.destroy_repo(repo_name) def test_api_create_repo_by_non_admin_no_parent_group_perms(self, backend): - repo_group_name = 'no-access' + repo_group_name = "no-access" fixture.create_repo_group(repo_group_name) - repo_name = 'no-access/api-repo' + repo_name = "no-access/api-repo" - id_, params = build_data( - self.apikey_regular, 'create_repo', - repo_name=repo_name, - repo_type=backend.alias) + id_, params = build_data(self.apikey_regular, "create_repo", repo_name=repo_name, repo_type=backend.alias) response = api_call(self.app, params) - expected = {'repo_group': 'Repository group `{}` does not exist'.format( - repo_group_name)} + expected = {"repo_group": "Repository group `{}` does not exist".format(repo_group_name)} assert_error(id_, expected, given=response.body) fixture.destroy_repo_group(repo_group_name) fixture.destroy_repo(repo_name) - def test_api_create_repo_non_admin_no_permission_to_create_to_root_level( - self, backend, user_util): - + def test_api_create_repo_non_admin_no_permission_to_create_to_root_level(self, backend, user_util): regular_user = user_util.create_user() regular_user_api_key = regular_user.api_key @@ -273,73 +259,69 @@ class TestCreateRepo(object): Session().add(usr) repo_name = backend.new_repo_name() - id_, params = build_data( - regular_user_api_key, 'create_repo', - repo_name=repo_name, - repo_type=backend.alias) + id_, params = build_data(regular_user_api_key, "create_repo", repo_name=repo_name, repo_type=backend.alias) response = api_call(self.app, params) - expected = { - "repo_name": "You do not have the permission to " - "store repositories in the root location."} + expected = {"repo_name": "You do not have the permission to store repositories in the root location."} assert_error(id_, expected, given=response.body) def test_api_create_repo_exists(self, backend): repo_name = backend.repo_name id_, params = build_data( - self.apikey, 'create_repo', + self.apikey, + "create_repo", repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, - repo_type=backend.alias,) + repo_type=backend.alias, + ) response = api_call(self.app, params) - expected = { - 'unique_repo_name': 'Repository with name `{}` already exists'.format( - repo_name)} + expected = {"unique_repo_name": "Repository with name `{}` already exists".format(repo_name)} assert_error(id_, expected, given=response.body) - @mock.patch.object(RepoModel, 'create', crash) + @mock.patch.object(RepoModel, "create", crash) def test_api_create_repo_exception_occurred(self, backend): - repo_name = 'api-repo-6' + repo_name = "api-repo-6" id_, params = build_data( - self.apikey, 'create_repo', + self.apikey, + "create_repo", repo_name=repo_name, owner=TEST_USER_ADMIN_LOGIN, - repo_type=backend.alias,) + repo_type=backend.alias, + ) response = api_call(self.app, params) - expected = 'failed to create repository `%s`' % (repo_name,) + expected = "failed to create repository `%s`" % (repo_name,) assert_error(id_, expected, given=response.body) - @pytest.mark.parametrize('parent_group, dirty_name, expected_name', [ - (None, 'foo bar x', 'foo-bar-x'), - ('foo', '/foo//bar x', 'foo/bar-x'), - ('foo-bar', 'foo-bar //bar x', 'foo-bar/bar-x'), - ]) - def test_create_repo_with_extra_slashes_in_name( - self, backend, parent_group, dirty_name, expected_name): - + @pytest.mark.parametrize( + "parent_group, dirty_name, expected_name", + [ + (None, "foo bar x", "foo-bar-x"), + ("foo", "/foo//bar x", "foo/bar-x"), + ("foo-bar", "foo-bar //bar x", "foo-bar/bar-x"), + ], + ) + def test_create_repo_with_extra_slashes_in_name(self, backend, parent_group, dirty_name, expected_name): if parent_group: gr = fixture.create_repo_group(parent_group) assert gr.group_name == parent_group id_, params = build_data( - self.apikey, 'create_repo', + self.apikey, + "create_repo", repo_name=dirty_name, repo_type=backend.alias, - owner=TEST_USER_ADMIN_LOGIN,) + owner=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) - expected ={ - "msg": "Created new repository `{}`".format(expected_name), - "task": None, - "success": True - } + expected = {"msg": "Created new repository `{}`".format(expected_name), "task": None, "success": True} assert_ok(id_, expected, response.body) repo = RepoModel().get_by_repo_name(expected_name) assert repo is not None expected = { - 'msg': 'Created new repository `%s`' % (expected_name,), - 'success': True, - 'task': None, + "msg": "Created new repository `%s`" % (expected_name,), + "success": True, + "task": None, } assert_ok(id_, expected, given=response.body) fixture.destroy_repo(expected_name) diff --git a/rhodecode/api/tests/test_create_repo_group.py b/rhodecode/api/tests/test_create_repo_group.py index 33f7443a..043d0f70 100644 --- a/rhodecode/api/tests/test_create_repo_group.py +++ b/rhodecode/api/tests/test_create_repo_group.py @@ -23,8 +23,7 @@ from rhodecode.model.meta import Session from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.user import UserModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash from rhodecode.tests.fixtures.rc_fixture import Fixture @@ -34,23 +33,22 @@ fixture = Fixture() @pytest.mark.usefixtures("testuser_api", "app") class TestCreateRepoGroup(object): def test_api_create_repo_group(self): - repo_group_name = 'api-repo-group' + repo_group_name = "api-repo-group" repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None id_, params = build_data( - self.apikey, 'create_repo_group', + self.apikey, + "create_repo_group", group_name=repo_group_name, - owner=TEST_USER_ADMIN_LOGIN,) + owner=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is not None - ret = { - 'msg': 'Created new repo group `%s`' % (repo_group_name,), - 'repo_group': repo_group.get_api_data() - } + ret = {"msg": "Created new repo group `%s`" % (repo_group_name,), "repo_group": repo_group.get_api_data()} expected = ret try: assert_ok(id_, expected, given=response.body) @@ -58,27 +56,26 @@ class TestCreateRepoGroup(object): fixture.destroy_repo_group(repo_group_name) def test_api_create_repo_group_in_another_group(self): - repo_group_name = 'api-repo-group' + repo_group_name = "api-repo-group" repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None # create the parent fixture.create_repo_group(repo_group_name) - full_repo_group_name = repo_group_name+'/'+repo_group_name + full_repo_group_name = repo_group_name + "/" + repo_group_name id_, params = build_data( - self.apikey, 'create_repo_group', + self.apikey, + "create_repo_group", group_name=full_repo_group_name, owner=TEST_USER_ADMIN_LOGIN, - copy_permissions=True) + copy_permissions=True, + ) response = api_call(self.app, params) repo_group = RepoGroupModel.cls.get_by_group_name(full_repo_group_name) assert repo_group is not None - ret = { - 'msg': 'Created new repo group `%s`' % (full_repo_group_name,), - 'repo_group': repo_group.get_api_data() - } + ret = {"msg": "Created new repo group `%s`" % (full_repo_group_name,), "repo_group": repo_group.get_api_data()} expected = ret try: assert_ok(id_, expected, given=response.body) @@ -87,83 +84,72 @@ class TestCreateRepoGroup(object): fixture.destroy_repo_group(repo_group_name) def test_api_create_repo_group_in_another_group_not_existing(self): - repo_group_name = 'api-repo-group-no' + repo_group_name = "api-repo-group-no" repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None - full_repo_group_name = repo_group_name+'/'+repo_group_name + full_repo_group_name = repo_group_name + "/" + repo_group_name id_, params = build_data( - self.apikey, 'create_repo_group', + self.apikey, + "create_repo_group", group_name=full_repo_group_name, owner=TEST_USER_ADMIN_LOGIN, - copy_permissions=True) + copy_permissions=True, + ) response = api_call(self.app, params) - expected = { - 'repo_group': - 'Parent repository group `{}` does not exist'.format( - repo_group_name)} + expected = {"repo_group": "Parent repository group `{}` does not exist".format(repo_group_name)} assert_error(id_, expected, given=response.body) def test_api_create_repo_group_that_exists(self): - repo_group_name = 'api-repo-group' + repo_group_name = "api-repo-group" repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None fixture.create_repo_group(repo_group_name) id_, params = build_data( - self.apikey, 'create_repo_group', + self.apikey, + "create_repo_group", group_name=repo_group_name, - owner=TEST_USER_ADMIN_LOGIN,) + owner=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) - expected = { - 'unique_repo_group_name': - 'Repository group with name `{}` already exists'.format( - repo_group_name)} + expected = {"unique_repo_group_name": "Repository group with name `{}` already exists".format(repo_group_name)} try: assert_error(id_, expected, given=response.body) finally: fixture.destroy_repo_group(repo_group_name) - def test_api_create_repo_group_regular_user_wit_root_location_perms( - self, user_util): + def test_api_create_repo_group_regular_user_wit_root_location_perms(self, user_util): regular_user = user_util.create_user() regular_user_api_key = regular_user.api_key - repo_group_name = 'api-repo-group-by-regular-user' + repo_group_name = "api-repo-group-by-regular-user" usr = UserModel().get_by_username(regular_user.username) usr.inherit_default_permissions = False Session().add(usr) - UserModel().grant_perm( - regular_user.username, 'hg.repogroup.create.true') + UserModel().grant_perm(regular_user.username, "hg.repogroup.create.true") Session().commit() repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None - id_, params = build_data( - regular_user_api_key, 'create_repo_group', - group_name=repo_group_name) + id_, params = build_data(regular_user_api_key, "create_repo_group", group_name=repo_group_name) response = api_call(self.app, params) repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is not None - expected = { - 'msg': 'Created new repo group `%s`' % (repo_group_name,), - 'repo_group': repo_group.get_api_data() - } + expected = {"msg": "Created new repo group `%s`" % (repo_group_name,), "repo_group": repo_group.get_api_data()} try: assert_ok(id_, expected, given=response.body) finally: fixture.destroy_repo_group(repo_group_name) - def test_api_create_repo_group_regular_user_with_admin_perms_to_parent( - self, user_util): - - repo_group_name = 'api-repo-group-parent' + def test_api_create_repo_group_regular_user_with_admin_perms_to_parent(self, user_util): + repo_group_name = "api-repo-group-parent" repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None @@ -178,21 +164,18 @@ class TestCreateRepoGroup(object): usr.inherit_default_permissions = False Session().add(usr) - RepoGroupModel().grant_user_permission( - repo_group_name, regular_user.username, 'group.admin') + RepoGroupModel().grant_user_permission(repo_group_name, regular_user.username, "group.admin") Session().commit() - full_repo_group_name = repo_group_name + '/' + repo_group_name - id_, params = build_data( - regular_user_api_key, 'create_repo_group', - group_name=full_repo_group_name) + full_repo_group_name = repo_group_name + "/" + repo_group_name + id_, params = build_data(regular_user_api_key, "create_repo_group", group_name=full_repo_group_name) response = api_call(self.app, params) repo_group = RepoGroupModel.cls.get_by_group_name(full_repo_group_name) assert repo_group is not None expected = { - 'msg': 'Created new repo group `{}`'.format(full_repo_group_name), - 'repo_group': repo_group.get_api_data() + "msg": "Created new repo group `{}`".format(full_repo_group_name), + "repo_group": repo_group.get_api_data(), } try: assert_ok(id_, expected, given=response.body) @@ -201,87 +184,83 @@ class TestCreateRepoGroup(object): fixture.destroy_repo_group(repo_group_name) def test_api_create_repo_group_regular_user_no_permission_to_create_to_root_level(self): - repo_group_name = 'api-repo-group' + repo_group_name = "api-repo-group" - id_, params = build_data( - self.apikey_regular, 'create_repo_group', - group_name=repo_group_name) + id_, params = build_data(self.apikey_regular, "create_repo_group", group_name=repo_group_name) response = api_call(self.app, params) - expected = { - 'repo_group': - 'You do not have the permission to store ' - 'repository groups in the root location.'} + expected = {"repo_group": "You do not have the permission to store repository groups in the root location."} assert_error(id_, expected, given=response.body) def test_api_create_repo_group_regular_user_no_parent_group_perms(self): - repo_group_name = 'api-repo-group-regular-user' + repo_group_name = "api-repo-group-regular-user" repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None # create the parent fixture.create_repo_group(repo_group_name) - full_repo_group_name = repo_group_name+'/'+repo_group_name + full_repo_group_name = repo_group_name + "/" + repo_group_name - id_, params = build_data( - self.apikey_regular, 'create_repo_group', - group_name=full_repo_group_name) + id_, params = build_data(self.apikey_regular, "create_repo_group", group_name=full_repo_group_name) response = api_call(self.app, params) expected = { - 'repo_group': - "You do not have the permissions to store " - "repository groups inside repository group `{}`".format(repo_group_name)} + "repo_group": "You do not have the permissions to store " + "repository groups inside repository group `{}`".format(repo_group_name) + } try: assert_error(id_, expected, given=response.body) finally: fixture.destroy_repo_group(repo_group_name) - def test_api_create_repo_group_regular_user_no_permission_to_specify_owner( - self): - repo_group_name = 'api-repo-group' + def test_api_create_repo_group_regular_user_no_permission_to_specify_owner(self): + repo_group_name = "api-repo-group" id_, params = build_data( - self.apikey_regular, 'create_repo_group', + self.apikey_regular, + "create_repo_group", group_name=repo_group_name, - owner=TEST_USER_ADMIN_LOGIN,) + owner=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) expected = "Only RhodeCode super-admin can specify `owner` param" assert_error(id_, expected, given=response.body) - @mock.patch.object(RepoGroupModel, 'create', crash) + @mock.patch.object(RepoGroupModel, "create", crash) def test_api_create_repo_group_exception_occurred(self): - repo_group_name = 'api-repo-group' + repo_group_name = "api-repo-group" repo_group = RepoGroupModel.cls.get_by_group_name(repo_group_name) assert repo_group is None id_, params = build_data( - self.apikey, 'create_repo_group', + self.apikey, + "create_repo_group", group_name=repo_group_name, - owner=TEST_USER_ADMIN_LOGIN,) + owner=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) - expected = 'failed to create repo group `%s`' % (repo_group_name,) + expected = "failed to create repo group `%s`" % (repo_group_name,) assert_error(id_, expected, given=response.body) def test_create_group_with_extra_slashes_in_name(self, user_util): existing_repo_group = user_util.create_repo_group() - dirty_group_name = '//{}//group2//'.format( - existing_repo_group.group_name) - cleaned_group_name = '{}/group2'.format( - existing_repo_group.group_name) + dirty_group_name = "//{}//group2//".format(existing_repo_group.group_name) + cleaned_group_name = "{}/group2".format(existing_repo_group.group_name) id_, params = build_data( - self.apikey, 'create_repo_group', + self.apikey, + "create_repo_group", group_name=dirty_group_name, - owner=TEST_USER_ADMIN_LOGIN,) + owner=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) repo_group = RepoGroupModel.cls.get_by_group_name(cleaned_group_name) expected = { - 'msg': 'Created new repo group `%s`' % (cleaned_group_name,), - 'repo_group': repo_group.get_api_data() + "msg": "Created new repo group `%s`" % (cleaned_group_name,), + "repo_group": repo_group.get_api_data(), } assert_ok(id_, expected, given=response.body) fixture.destroy_repo_group(cleaned_group_name) diff --git a/rhodecode/api/tests/test_create_user.py b/rhodecode/api/tests/test_create_user.py index cafb6e25..05df9317 100644 --- a/rhodecode/api/tests/test_create_user.py +++ b/rhodecode/api/tests/test_create_user.py @@ -21,10 +21,8 @@ import pytest from rhodecode.lib.auth import check_password from rhodecode.model.user import UserModel -from rhodecode.tests import ( - TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL) -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, jsonify, crash) +from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, jsonify, crash from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.model.db import RepoGroup @@ -37,10 +35,8 @@ fixture = Fixture() class TestCreateUser(object): def test_api_create_existing_user(self): id_, params = build_data( - self.apikey, 'create_user', - username=TEST_USER_ADMIN_LOGIN, - email='test@foo.com', - password='trololo') + self.apikey, "create_user", username=TEST_USER_ADMIN_LOGIN, email="test@foo.com", password="trololo" + ) response = api_call(self.app, params) expected = "user `%s` already exist" % (TEST_USER_ADMIN_LOGIN,) @@ -48,68 +44,63 @@ class TestCreateUser(object): def test_api_create_user_with_existing_email(self): id_, params = build_data( - self.apikey, 'create_user', - username=TEST_USER_ADMIN_LOGIN + 'new', + self.apikey, + "create_user", + username=TEST_USER_ADMIN_LOGIN + "new", email=TEST_USER_REGULAR_EMAIL, - password='trololo') + password="trololo", + ) response = api_call(self.app, params) expected = "email `%s` already exist" % (TEST_USER_REGULAR_EMAIL,) assert_error(id_, expected, given=response.body) def test_api_create_user_with_wrong_username(self): - bad_username = '<> HELLO WORLD <>' + bad_username = "<> HELLO WORLD <>" id_, params = build_data( - self.apikey, 'create_user', - username=bad_username, - email='new@email.com', - password='trololo') + self.apikey, "create_user", username=bad_username, email="new@email.com", password="trololo" + ) response = api_call(self.app, params) - expected = {'username': - "Username may only contain alphanumeric characters " - "underscores, periods or dashes and must begin with " - "alphanumeric character or underscore"} + expected = { + "username": "Username may only contain alphanumeric characters " + "underscores, periods or dashes and must begin with " + "alphanumeric character or underscore" + } assert_error(id_, expected, given=response.body) def test_api_create_user(self): - username = 'test_new_api_user' + username = "test_new_api_user" email = username + "@foo.com" id_, params = build_data( - self.apikey, 'create_user', - username=username, - email=email, - description='CTO of Things', - password='example') + self.apikey, "create_user", username=username, email=email, description="CTO of Things", password="example" + ) response = api_call(self.app, params) usr = UserModel().get_by_username(username) ret = { - 'msg': 'created new user `%s`' % (username,), - 'user': jsonify(usr.get_api_data(include_secrets=True)), + "msg": "created new user `%s`" % (username,), + "user": jsonify(usr.get_api_data(include_secrets=True)), } try: expected = ret - assert check_password('example', usr.password) + assert check_password("example", usr.password) assert_ok(id_, expected, given=response.body) finally: fixture.destroy_user(usr.user_id) def test_api_create_user_without_password(self): - username = 'test_new_api_user_passwordless' + username = "test_new_api_user_passwordless" email = username + "@foo.com" - id_, params = build_data( - self.apikey, 'create_user', - username=username, - email=email) + id_, params = build_data(self.apikey, "create_user", username=username, email=email) response = api_call(self.app, params) usr = UserModel().get_by_username(username) ret = { - 'msg': 'created new user `%s`' % (username,), - 'user': jsonify(usr.get_api_data(include_secrets=True)), + "msg": "created new user `%s`" % (username,), + "user": jsonify(usr.get_api_data(include_secrets=True)), } try: expected = ret @@ -118,19 +109,16 @@ class TestCreateUser(object): fixture.destroy_user(usr.user_id) def test_api_create_user_with_extern_name(self): - username = 'test_new_api_user_passwordless' + username = "test_new_api_user_passwordless" email = username + "@foo.com" - id_, params = build_data( - self.apikey, 'create_user', - username=username, - email=email, extern_name='rhodecode') + id_, params = build_data(self.apikey, "create_user", username=username, email=email, extern_name="rhodecode") response = api_call(self.app, params) usr = UserModel().get_by_username(username) ret = { - 'msg': 'created new user `%s`' % (username,), - 'user': jsonify(usr.get_api_data(include_secrets=True)), + "msg": "created new user `%s`" % (username,), + "user": jsonify(usr.get_api_data(include_secrets=True)), } try: expected = ret @@ -139,20 +127,23 @@ class TestCreateUser(object): fixture.destroy_user(usr.user_id) def test_api_create_user_with_password_change(self): - username = 'test_new_api_user_password_change' + username = "test_new_api_user_password_change" email = username + "@foo.com" id_, params = build_data( - self.apikey, 'create_user', + self.apikey, + "create_user", username=username, - email=email, extern_name='rhodecode', - force_password_change=True) + email=email, + extern_name="rhodecode", + force_password_change=True, + ) response = api_call(self.app, params) usr = UserModel().get_by_username(username) ret = { - 'msg': 'created new user `%s`' % (username,), - 'user': jsonify(usr.get_api_data(include_secrets=True)), + "msg": "created new user `%s`" % (username,), + "user": jsonify(usr.get_api_data(include_secrets=True)), } try: expected = ret @@ -161,20 +152,23 @@ class TestCreateUser(object): fixture.destroy_user(usr.user_id) def test_api_create_user_with_personal_repo_group(self): - username = 'test_new_api_user_personal_group' + username = "test_new_api_user_personal_group" email = username + "@foo.com" id_, params = build_data( - self.apikey, 'create_user', + self.apikey, + "create_user", username=username, - email=email, extern_name='rhodecode', - create_personal_repo_group=True) + email=email, + extern_name="rhodecode", + create_personal_repo_group=True, + ) response = api_call(self.app, params) usr = UserModel().get_by_username(username) ret = { - 'msg': 'created new user `%s`' % (username,), - 'user': jsonify(usr.get_api_data(include_secrets=True)), + "msg": "created new user `%s`" % (username,), + "user": jsonify(usr.get_api_data(include_secrets=True)), } personal_group = RepoGroup.get_by_group_name(username) @@ -189,17 +183,12 @@ class TestCreateUser(object): fixture.destroy_repo_group(username) fixture.destroy_user(usr.user_id) - @mock.patch.object(UserModel, 'create_or_update', crash) + @mock.patch.object(UserModel, "create_or_update", crash) def test_api_create_user_when_exception_happened(self): - - username = 'test_new_api_user' + username = "test_new_api_user" email = username + "@foo.com" - id_, params = build_data( - self.apikey, 'create_user', - username=username, - email=email, - password='trololo') + id_, params = build_data(self.apikey, "create_user", username=username, email=email, password="trololo") response = api_call(self.app, params) - expected = 'failed to create user `%s`' % (username,) + expected = "failed to create user `%s`" % (username,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_create_user_group.py b/rhodecode/api/tests/test_create_user_group.py index ce0c520a..13d83307 100644 --- a/rhodecode/api/tests/test_create_user_group.py +++ b/rhodecode/api/tests/test_create_user_group.py @@ -22,8 +22,7 @@ import pytest from rhodecode.model.meta import Session from rhodecode.model.user import UserModel from rhodecode.model.user_group import UserGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash, jsonify) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash, jsonify from rhodecode.tests.fixtures.rc_fixture import Fixture @@ -32,60 +31,47 @@ class TestCreateUserGroup(object): fixture = Fixture() def test_api_create_user_group(self): - group_name = 'some_new_group' - id_, params = build_data( - self.apikey, 'create_user_group', group_name=group_name) + group_name = "some_new_group" + id_, params = build_data(self.apikey, "create_user_group", group_name=group_name) response = api_call(self.app, params) ret = { - 'msg': 'created new user group `%s`' % (group_name,), - 'user_group': jsonify( - UserGroupModel() - .get_by_name(group_name) - .get_api_data() - ) + "msg": "created new user group `%s`" % (group_name,), + "user_group": jsonify(UserGroupModel().get_by_name(group_name).get_api_data()), } expected = ret assert_ok(id_, expected, given=response.body) self.fixture.destroy_user_group(group_name) def test_api_create_user_group_regular_user(self): - group_name = 'some_new_group' + group_name = "some_new_group" usr = UserModel().get_by_username(self.TEST_USER_LOGIN) usr.inherit_default_permissions = False Session().add(usr) - UserModel().grant_perm( - self.TEST_USER_LOGIN, 'hg.usergroup.create.true') + UserModel().grant_perm(self.TEST_USER_LOGIN, "hg.usergroup.create.true") Session().commit() - id_, params = build_data( - self.apikey_regular, 'create_user_group', group_name=group_name) + id_, params = build_data(self.apikey_regular, "create_user_group", group_name=group_name) response = api_call(self.app, params) expected = { - 'msg': 'created new user group `%s`' % (group_name,), - 'user_group': jsonify( - UserGroupModel() - .get_by_name(group_name) - .get_api_data() - ) + "msg": "created new user group `%s`" % (group_name,), + "user_group": jsonify(UserGroupModel().get_by_name(group_name).get_api_data()), } try: assert_ok(id_, expected, given=response.body) finally: self.fixture.destroy_user_group(group_name) - UserModel().revoke_perm( - self.TEST_USER_LOGIN, 'hg.usergroup.create.true') + UserModel().revoke_perm(self.TEST_USER_LOGIN, "hg.usergroup.create.true") usr = UserModel().get_by_username(self.TEST_USER_LOGIN) usr.inherit_default_permissions = True Session().add(usr) Session().commit() def test_api_create_user_group_regular_user_no_permission(self): - group_name = 'some_new_group' - id_, params = build_data( - self.apikey_regular, 'create_user_group', group_name=group_name) + group_name = "some_new_group" + id_, params = build_data(self.apikey_regular, "create_user_group", group_name=group_name) response = api_call(self.app, params) expected = "Access was denied to this resource." assert_error(id_, expected, given=response.body) @@ -94,32 +80,29 @@ class TestCreateUserGroup(object): group = user_util.create_user_group() group_name = group.users_group_name - id_, params = build_data( - self.apikey, 'create_user_group', group_name=group_name) + id_, params = build_data(self.apikey, "create_user_group", group_name=group_name) response = api_call(self.app, params) expected = "user group `%s` already exist" % (group_name,) assert_error(id_, expected, given=response.body) - @mock.patch.object(UserGroupModel, 'create', crash) + @mock.patch.object(UserGroupModel, "create", crash) def test_api_create_user_group_exception_occurred(self): - group_name = 'exception_happens' - id_, params = build_data( - self.apikey, 'create_user_group', group_name=group_name) + group_name = "exception_happens" + id_, params = build_data(self.apikey, "create_user_group", group_name=group_name) response = api_call(self.app, params) - expected = 'failed to create group `%s`' % (group_name,) + expected = "failed to create group `%s`" % (group_name,) assert_error(id_, expected, given=response.body) def test_api_create_user_group_with_wrong_name(self, user_util): - - group_name = 'wrong NAME <>' - id_, params = build_data( - self.apikey, 'create_user_group', group_name=group_name) + group_name = "wrong NAME <>" + id_, params = build_data(self.apikey, "create_user_group", group_name=group_name) response = api_call(self.app, params) - expected = {"user_group_name": - "Allowed in name are letters, numbers, and `-`, `_`, " - "`.` Name must start with a letter or number. " - "Got `{}`".format(group_name)} + expected = { + "user_group_name": "Allowed in name are letters, numbers, and `-`, `_`, " + "`.` Name must start with a letter or number. " + "Got `{}`".format(group_name) + } assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_delete_gist.py b/rhodecode/api/tests/test_delete_gist.py index cec1455c..5799feb3 100644 --- a/rhodecode/api/tests/test_delete_gist.py +++ b/rhodecode/api/tests/test_delete_gist.py @@ -20,40 +20,36 @@ import mock import pytest from rhodecode.model.gist import GistModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestApiDeleteGist(object): def test_api_delete_gist(self, gist_util): gist_id = gist_util.create_gist().gist_access_id - id_, params = build_data(self.apikey, 'delete_gist', gistid=gist_id) + id_, params = build_data(self.apikey, "delete_gist", gistid=gist_id) response = api_call(self.app, params) - expected = {'gist': None, 'msg': 'deleted gist ID:%s' % (gist_id,)} + expected = {"gist": None, "msg": "deleted gist ID:%s" % (gist_id,)} assert_ok(id_, expected, given=response.body) def test_api_delete_gist_regular_user(self, gist_util): - gist_id = gist_util.create_gist( - owner=self.TEST_USER_LOGIN).gist_access_id - id_, params = build_data( - self.apikey_regular, 'delete_gist', gistid=gist_id) + gist_id = gist_util.create_gist(owner=self.TEST_USER_LOGIN).gist_access_id + id_, params = build_data(self.apikey_regular, "delete_gist", gistid=gist_id) response = api_call(self.app, params) - expected = {'gist': None, 'msg': 'deleted gist ID:%s' % (gist_id,)} + expected = {"gist": None, "msg": "deleted gist ID:%s" % (gist_id,)} assert_ok(id_, expected, given=response.body) def test_api_delete_gist_regular_user_no_permission(self, gist_util): gist_id = gist_util.create_gist().gist_access_id - id_, params = build_data( - self.apikey_regular, 'delete_gist', gistid=gist_id) + id_, params = build_data(self.apikey_regular, "delete_gist", gistid=gist_id) response = api_call(self.app, params) - expected = 'gist `%s` does not exist' % (gist_id,) + expected = "gist `%s` does not exist" % (gist_id,) assert_error(id_, expected, given=response.body) - @mock.patch.object(GistModel, 'delete', crash) + @mock.patch.object(GistModel, "delete", crash) def test_api_delete_gist_exception_occurred(self, gist_util): gist_id = gist_util.create_gist().gist_access_id - id_, params = build_data(self.apikey, 'delete_gist', gistid=gist_id) + id_, params = build_data(self.apikey, "delete_gist", gistid=gist_id) response = api_call(self.app, params) - expected = 'failed to delete gist ID:%s' % (gist_id,) + expected = "failed to delete gist ID:%s" % (gist_id,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_delete_repo.py b/rhodecode/api/tests/test_delete_repo.py index 1934b60e..8893d136 100644 --- a/rhodecode/api/tests/test_delete_repo.py +++ b/rhodecode/api/tests/test_delete_repo.py @@ -20,8 +20,7 @@ import mock import pytest from rhodecode.model.repo import RepoModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") @@ -30,43 +29,49 @@ class TestApiDeleteRepo(object): repo = backend.create_repo() repo_name = repo.repo_name id_, params = build_data( - self.apikey, 'delete_repo', repoid=repo.repo_name, ) + self.apikey, + "delete_repo", + repoid=repo.repo_name, + ) response = api_call(self.app, params) - expected = { - 'msg': 'Deleted repository `%s`' % (repo_name,), - 'success': True - } + expected = {"msg": "Deleted repository `%s`" % (repo_name,), "success": True} assert_ok(id_, expected, given=response.body) def test_api_delete_repo_by_non_admin(self, backend, user_regular): repo = backend.create_repo(cur_user=user_regular.username) repo_name = repo.repo_name id_, params = build_data( - user_regular.api_key, 'delete_repo', repoid=repo.repo_name, ) + user_regular.api_key, + "delete_repo", + repoid=repo.repo_name, + ) response = api_call(self.app, params) - expected = { - 'msg': 'Deleted repository `%s`' % (repo_name,), - 'success': True - } + expected = {"msg": "Deleted repository `%s`" % (repo_name,), "success": True} assert_ok(id_, expected, given=response.body) def test_api_delete_repo_by_non_admin_no_permission(self, backend): repo = backend.create_repo() repo_name = repo.repo_name id_, params = build_data( - self.apikey_regular, 'delete_repo', repoid=repo.repo_name, ) + self.apikey_regular, + "delete_repo", + repoid=repo.repo_name, + ) response = api_call(self.app, params) - expected = 'repository `%s` does not exist' % (repo_name) + expected = "repository `%s` does not exist" % (repo_name) assert_error(id_, expected, given=response.body) def test_api_delete_repo_exception_occurred(self, backend): repo = backend.create_repo() repo_name = repo.repo_name id_, params = build_data( - self.apikey, 'delete_repo', repoid=repo.repo_name, ) - with mock.patch.object(RepoModel, 'delete', crash): + self.apikey, + "delete_repo", + repoid=repo.repo_name, + ) + with mock.patch.object(RepoModel, "delete", crash): response = api_call(self.app, params) - expected = 'failed to delete repository `%s`' % (repo_name,) + expected = "failed to delete repository `%s`" % (repo_name,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_delete_repo_group.py b/rhodecode/api/tests/test_delete_repo_group.py index 8034fc17..2b783678 100644 --- a/rhodecode/api/tests/test_delete_repo_group.py +++ b/rhodecode/api/tests/test_delete_repo_group.py @@ -21,8 +21,7 @@ import pytest from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.user import UserModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") @@ -32,15 +31,13 @@ class TestApiDeleteRepoGroup(object): repo_group_name = repo_group.group_name repo_group_id = repo_group.group_id id_, params = build_data( - self.apikey, 'delete_repo_group', repogroupid=repo_group_name, ) + self.apikey, + "delete_repo_group", + repogroupid=repo_group_name, + ) response = api_call(self.app, params) - ret = { - 'msg': 'deleted repo group ID:%s %s' % ( - repo_group_id, repo_group_name - ), - 'repo_group': None - } + ret = {"msg": "deleted repo group ID:%s %s" % (repo_group_id, repo_group_name), "repo_group": None} expected = ret assert_ok(id_, expected, given=response.body) gr = RepoGroupModel()._get_repo_group(repo_group_name) @@ -52,19 +49,16 @@ class TestApiDeleteRepoGroup(object): repo_group_id = repo_group.group_id user = UserModel().get_by_username(self.TEST_USER_LOGIN) - user_util.grant_user_permission_to_repo_group( - repo_group, user, 'group.admin') + user_util.grant_user_permission_to_repo_group(repo_group, user, "group.admin") id_, params = build_data( - self.apikey, 'delete_repo_group', repogroupid=repo_group_name, ) + self.apikey, + "delete_repo_group", + repogroupid=repo_group_name, + ) response = api_call(self.app, params) - ret = { - 'msg': 'deleted repo group ID:%s %s' % ( - repo_group_id, repo_group_name - ), - 'repo_group': None - } + ret = {"msg": "deleted repo group ID:%s %s" % (repo_group_id, repo_group_name), "repo_group": None} expected = ret assert_ok(id_, expected, given=response.body) gr = RepoGroupModel()._get_repo_group(repo_group_name) @@ -75,10 +69,11 @@ class TestApiDeleteRepoGroup(object): repo_group_name = repo_group.group_name id_, params = build_data( - self.apikey_regular, 'delete_repo_group', - repogroupid=repo_group_name, ) + self.apikey_regular, + "delete_repo_group", + repogroupid=repo_group_name, + ) response = api_call(self.app, params) - expected = 'repository group `%s` does not exist' % ( - repo_group_name,) + expected = "repository group `%s` does not exist" % (repo_group_name,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_delete_user.py b/rhodecode/api/tests/test_delete_user.py index c02ff4dc..2ed7efb3 100644 --- a/rhodecode/api/tests/test_delete_user.py +++ b/rhodecode/api/tests/test_delete_user.py @@ -21,8 +21,7 @@ import mock import pytest from rhodecode.model.user import UserModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash @pytest.mark.usefixtures("testuser_api", "app") @@ -33,23 +32,24 @@ class TestDeleteUser(object): username = usr.username usr_id = usr.user_id - id_, params = build_data(self.apikey, 'delete_user', userid=username) + id_, params = build_data(self.apikey, "delete_user", userid=username) response = api_call(self.app, params) - ret = {'msg': 'deleted user ID:%s %s' % (usr_id, username), - 'user': None} + ret = {"msg": "deleted user ID:%s %s" % (usr_id, username), "user": None} expected = ret assert_ok(id_, expected, given=response.body) - @mock.patch.object(UserModel, 'delete', crash) + @mock.patch.object(UserModel, "delete", crash) def test_api_delete_user_when_exception_happened(self, user_util): usr = user_util.create_user() username = usr.username id_, params = build_data( - self.apikey, 'delete_user', userid=username, ) + self.apikey, + "delete_user", + userid=username, + ) response = api_call(self.app, params) - ret = 'failed to delete user ID:%s %s' % (usr.user_id, - usr.username) + ret = "failed to delete user ID:%s %s" % (usr.user_id, usr.username) expected = ret assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_delete_user_group.py b/rhodecode/api/tests/test_delete_user_group.py index 325e98af..10e933c9 100644 --- a/rhodecode/api/tests/test_delete_user_group.py +++ b/rhodecode/api/tests/test_delete_user_group.py @@ -22,8 +22,7 @@ import pytest from rhodecode.model.user import UserModel from rhodecode.model.user_group import UserGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") @@ -32,14 +31,10 @@ class TestDeleteUserGroup(object): user_group = user_util.create_user_group(auto_cleanup=False) group_name = user_group.users_group_name group_id = user_group.users_group_id - id_, params = build_data( - self.apikey, 'delete_user_group', usergroupid=group_name) + id_, params = build_data(self.apikey, "delete_user_group", usergroupid=group_name) response = api_call(self.app, params) - expected = { - 'user_group': None, - 'msg': 'deleted user group ID:%s %s' % (group_id, group_name) - } + expected = {"user_group": None, "msg": "deleted user group ID:%s %s" % (group_id, group_name)} assert_ok(id_, expected, given=response.body) def test_api_delete_user_group_regular_user(self, user_util): @@ -48,28 +43,22 @@ class TestDeleteUserGroup(object): group_id = ugroup.users_group_id user = UserModel().get_by_username(self.TEST_USER_LOGIN) - user_util.grant_user_permission_to_user_group( - ugroup, user, 'usergroup.admin') + user_util.grant_user_permission_to_user_group(ugroup, user, "usergroup.admin") - id_, params = build_data( - self.apikey_regular, 'delete_user_group', usergroupid=group_name) + id_, params = build_data(self.apikey_regular, "delete_user_group", usergroupid=group_name) response = api_call(self.app, params) - expected = { - 'user_group': None, - 'msg': 'deleted user group ID:%s %s' % (group_id, group_name) - } + expected = {"user_group": None, "msg": "deleted user group ID:%s %s" % (group_id, group_name)} assert_ok(id_, expected, given=response.body) def test_api_delete_user_group_regular_user_no_permission(self, user_util): user_group = user_util.create_user_group() group_name = user_group.users_group_name - id_, params = build_data( - self.apikey_regular, 'delete_user_group', usergroupid=group_name) + id_, params = build_data(self.apikey_regular, "delete_user_group", usergroupid=group_name) response = api_call(self.app, params) - expected = 'user group `%s` does not exist' % (group_name) + expected = "user group `%s` does not exist" % (group_name) assert_error(id_, expected, given=response.body) def test_api_delete_user_group_that_is_assigned(self, backend, user_util): @@ -77,13 +66,10 @@ class TestDeleteUserGroup(object): group_name = ugroup.users_group_name repo = backend.create_repo() - ugr_to_perm = user_util.grant_user_group_permission_to_repo( - repo, ugroup, 'repository.write') - msg = 'UserGroup assigned to %s' % (ugr_to_perm.repository) + ugr_to_perm = user_util.grant_user_group_permission_to_repo(repo, ugroup, "repository.write") + msg = "UserGroup assigned to %s" % (ugr_to_perm.repository) - id_, params = build_data( - self.apikey, 'delete_user_group', - usergroupid=group_name) + id_, params = build_data(self.apikey, "delete_user_group", usergroupid=group_name) response = api_call(self.app, params) expected = msg @@ -93,12 +79,9 @@ class TestDeleteUserGroup(object): ugroup = user_util.create_user_group() group_name = ugroup.users_group_name group_id = ugroup.users_group_id - id_, params = build_data( - self.apikey, 'delete_user_group', - usergroupid=group_name) + id_, params = build_data(self.apikey, "delete_user_group", usergroupid=group_name) - with mock.patch.object(UserGroupModel, 'delete', crash): + with mock.patch.object(UserGroupModel, "delete", crash): response = api_call(self.app, params) - expected = 'failed to delete user group ID:%s %s' % ( - group_id, group_name) + expected = "failed to delete user group ID:%s %s" % (group_id, group_name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_deprecated_api.py b/rhodecode/api/tests/test_deprecated_api.py index 4b60801c..4728da82 100644 --- a/rhodecode/api/tests/test_deprecated_api.py +++ b/rhodecode/api/tests/test_deprecated_api.py @@ -21,29 +21,25 @@ import pytest from rhodecode.api.views import deprecated_api from rhodecode.lib.ext_json import json -from rhodecode.api.tests.utils import ( - build_data, api_call) +from rhodecode.api.tests.utils import build_data, api_call @pytest.mark.usefixtures("testuser_api", "app") class TestCommitComment(object): def test_deprecated_message_in_docstring(self): docstring = deprecated_api.changeset_comment.__doc__ - assert '.. deprecated:: 3.4.0' in docstring - assert 'Please use method `comment_commit` instead.' in docstring + assert ".. deprecated:: 3.4.0" in docstring + assert "Please use method `comment_commit` instead." in docstring def test_deprecated_message_in_retvalue(self): - - id_, params = build_data( - self.apikey, 'show_ip') + id_, params = build_data(self.apikey, "show_ip") response = api_call(self.app, params) expected = { - 'id': id_, - 'error': None, - 'result': json.loads(response.body)['result'], - 'DEPRECATION_WARNING': - 'DEPRECATED METHOD Please use method `get_ip` instead.' + "id": id_, + "error": None, + "result": json.loads(response.body)["result"], + "DEPRECATION_WARNING": "DEPRECATED METHOD Please use method `get_ip` instead.", } assert expected == json.loads(response.body) @@ -74,4 +70,4 @@ class TestCommitComment(object): # call_args[0] == # 'DEPRECATED API CALL on function %s, please use `%s` instead') # assert call_args[1].__name__ == 'api_method' - # assert call_args[2] == 'new_method' \ No newline at end of file + # assert call_args[2] == 'new_method' diff --git a/rhodecode/api/tests/test_fork_repo.py b/rhodecode/api/tests/test_fork_repo.py index 45294e16..5199b3ad 100644 --- a/rhodecode/api/tests/test_fork_repo.py +++ b/rhodecode/api/tests/test_fork_repo.py @@ -25,8 +25,7 @@ from rhodecode.model.repo import RepoModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.user import UserModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash from rhodecode.tests.fixtures.rc_fixture import Fixture @@ -36,20 +35,18 @@ fixture = Fixture() @pytest.mark.usefixtures("testuser_api", "app") class TestApiForkRepo(object): def test_api_fork_repo(self, backend): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() id_, params = build_data( - self.apikey, 'fork_repo', - repoid=source_name, - fork_name=fork_name, - owner=TEST_USER_ADMIN_LOGIN) + self.apikey, "fork_repo", repoid=source_name, fork_name=fork_name, owner=TEST_USER_ADMIN_LOGIN + ) response = api_call(self.app, params) expected = { - 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name), - 'success': True, - 'task': None, + "msg": "Created fork of `%s` as `%s`" % (source_name, fork_name), + "success": True, + "task": None, } try: assert_ok(id_, expected, given=response.body) @@ -57,20 +54,18 @@ class TestApiForkRepo(object): fixture.destroy_repo(fork_name) def test_api_fork_repo_into_group(self, backend, user_util): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name repo_group = user_util.create_repo_group() - fork_name = '%s/api-repo-fork' % repo_group.group_name + fork_name = "%s/api-repo-fork" % repo_group.group_name id_, params = build_data( - self.apikey, 'fork_repo', - repoid=source_name, - fork_name=fork_name, - owner=TEST_USER_ADMIN_LOGIN) + self.apikey, "fork_repo", repoid=source_name, fork_name=fork_name, owner=TEST_USER_ADMIN_LOGIN + ) response = api_call(self.app, params) ret = { - 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name), - 'success': True, - 'task': None, + "msg": "Created fork of `%s` as `%s`" % (source_name, fork_name), + "success": True, + "task": None, } expected = ret try: @@ -79,19 +74,16 @@ class TestApiForkRepo(object): fixture.destroy_repo(fork_name) def test_api_fork_repo_non_admin(self, backend): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() - id_, params = build_data( - self.apikey_regular, 'fork_repo', - repoid=source_name, - fork_name=fork_name) + id_, params = build_data(self.apikey_regular, "fork_repo", repoid=source_name, fork_name=fork_name) response = api_call(self.app, params) expected = { - 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name), - 'success': True, - 'task': None, + "msg": "Created fork of `%s` as `%s`" % (source_name, fork_name), + "success": True, + "task": None, } try: assert_ok(id_, expected, given=response.body) @@ -99,44 +91,35 @@ class TestApiForkRepo(object): fixture.destroy_repo(fork_name) def test_api_fork_repo_non_admin_into_group_no_permission(self, backend, user_util): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name repo_group = user_util.create_repo_group() repo_group_name = repo_group.group_name - fork_name = '%s/api-repo-fork' % repo_group_name + fork_name = "%s/api-repo-fork" % repo_group_name - id_, params = build_data( - self.apikey_regular, 'fork_repo', - repoid=source_name, - fork_name=fork_name) + id_, params = build_data(self.apikey_regular, "fork_repo", repoid=source_name, fork_name=fork_name) response = api_call(self.app, params) - expected = { - 'repo_group': 'Repository group `{}` does not exist'.format( - repo_group_name)} + expected = {"repo_group": "Repository group `{}` does not exist".format(repo_group_name)} try: assert_error(id_, expected, given=response.body) finally: fixture.destroy_repo(fork_name) def test_api_fork_repo_non_admin_into_group(self, backend, user_util): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name repo_group = user_util.create_repo_group() - fork_name = '%s/api-repo-fork' % repo_group.group_name + fork_name = "%s/api-repo-fork" % repo_group.group_name - RepoGroupModel().grant_user_permission( - repo_group, self.TEST_USER_LOGIN, 'group.admin') + RepoGroupModel().grant_user_permission(repo_group, self.TEST_USER_LOGIN, "group.admin") Session().commit() - id_, params = build_data( - self.apikey_regular, 'fork_repo', - repoid=source_name, - fork_name=fork_name) + id_, params = build_data(self.apikey_regular, "fork_repo", repoid=source_name, fork_name=fork_name) response = api_call(self.app, params) expected = { - 'msg': 'Created fork of `%s` as `%s`' % (source_name, fork_name), - 'success': True, - 'task': None, + "msg": "Created fork of `%s` as `%s`" % (source_name, fork_name), + "success": True, + "task": None, } try: assert_ok(id_, expected, given=response.body) @@ -144,134 +127,99 @@ class TestApiForkRepo(object): fixture.destroy_repo(fork_name) def test_api_fork_repo_non_admin_specify_owner(self, backend): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() id_, params = build_data( - self.apikey_regular, 'fork_repo', - repoid=source_name, - fork_name=fork_name, - owner=TEST_USER_ADMIN_LOGIN) + self.apikey_regular, "fork_repo", repoid=source_name, fork_name=fork_name, owner=TEST_USER_ADMIN_LOGIN + ) response = api_call(self.app, params) - expected = 'Only RhodeCode super-admin can specify `owner` param' + expected = "Only RhodeCode super-admin can specify `owner` param" assert_error(id_, expected, given=response.body) - def test_api_fork_repo_non_admin_no_permission_of_source_repo( - self, backend): - source_name = backend['minimal'].repo_name - RepoModel().grant_user_permission(repo=source_name, - user=self.TEST_USER_LOGIN, - perm='repository.none') + def test_api_fork_repo_non_admin_no_permission_of_source_repo(self, backend): + source_name = backend["minimal"].repo_name + RepoModel().grant_user_permission(repo=source_name, user=self.TEST_USER_LOGIN, perm="repository.none") fork_name = backend.new_repo_name() - id_, params = build_data( - self.apikey_regular, 'fork_repo', - repoid=backend.repo_name, - fork_name=fork_name) + id_, params = build_data(self.apikey_regular, "fork_repo", repoid=backend.repo_name, fork_name=fork_name) response = api_call(self.app, params) - expected = 'repository `%s` does not exist' % (backend.repo_name) + expected = "repository `%s` does not exist" % (backend.repo_name) assert_error(id_, expected, given=response.body) - def test_api_fork_repo_non_admin_no_permission_to_fork_to_root_level( - self, backend, user_util): - + def test_api_fork_repo_non_admin_no_permission_to_fork_to_root_level(self, backend, user_util): regular_user = user_util.create_user() regular_user_api_key = regular_user.api_key usr = UserModel().get_by_username(regular_user.username) usr.inherit_default_permissions = False Session().add(usr) - UserModel().grant_perm(regular_user.username, 'hg.fork.repository') + UserModel().grant_perm(regular_user.username, "hg.fork.repository") - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() - id_, params = build_data( - regular_user_api_key, 'fork_repo', - repoid=source_name, - fork_name=fork_name) + id_, params = build_data(regular_user_api_key, "fork_repo", repoid=source_name, fork_name=fork_name) response = api_call(self.app, params) - expected = { - "repo_name": "You do not have the permission to " - "store repositories in the root location."} + expected = {"repo_name": "You do not have the permission to store repositories in the root location."} assert_error(id_, expected, given=response.body) - def test_api_fork_repo_non_admin_no_permission_to_fork( - self, backend, user_util): - + def test_api_fork_repo_non_admin_no_permission_to_fork(self, backend, user_util): regular_user = user_util.create_user() regular_user_api_key = regular_user.api_key usr = UserModel().get_by_username(regular_user.username) usr.inherit_default_permissions = False Session().add(usr) - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() - id_, params = build_data( - regular_user_api_key, 'fork_repo', - repoid=source_name, - fork_name=fork_name) + id_, params = build_data(regular_user_api_key, "fork_repo", repoid=source_name, fork_name=fork_name) response = api_call(self.app, params) expected = "Access was denied to this resource." assert_error(id_, expected, given=response.body) def test_api_fork_repo_unknown_owner(self, backend): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() - owner = 'i-dont-exist' - id_, params = build_data( - self.apikey, 'fork_repo', - repoid=source_name, - fork_name=fork_name, - owner=owner) + owner = "i-dont-exist" + id_, params = build_data(self.apikey, "fork_repo", repoid=source_name, fork_name=fork_name, owner=owner) response = api_call(self.app, params) - expected = 'user `%s` does not exist' % (owner,) + expected = "user `%s` does not exist" % (owner,) assert_error(id_, expected, given=response.body) def test_api_fork_repo_fork_exists(self, backend): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() fork_repo = fixture.create_fork(source_name, fork_name) id_, params = build_data( - self.apikey, 'fork_repo', - repoid=source_name, - fork_name=fork_name, - owner=TEST_USER_ADMIN_LOGIN) + self.apikey, "fork_repo", repoid=source_name, fork_name=fork_name, owner=TEST_USER_ADMIN_LOGIN + ) response = api_call(self.app, params) try: - expected = { - 'unique_repo_name': 'Repository with name `{}` already exists'.format( - fork_name)} + expected = {"unique_repo_name": "Repository with name `{}` already exists".format(fork_name)} assert_error(id_, expected, given=response.body) finally: fixture.destroy_repo(fork_repo.repo_name) def test_api_fork_repo_repo_exists(self, backend): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = source_name id_, params = build_data( - self.apikey, 'fork_repo', - repoid=source_name, - fork_name=fork_name, - owner=TEST_USER_ADMIN_LOGIN) + self.apikey, "fork_repo", repoid=source_name, fork_name=fork_name, owner=TEST_USER_ADMIN_LOGIN + ) response = api_call(self.app, params) - expected = { - 'unique_repo_name': 'Repository with name `{}` already exists'.format( - fork_name)} + expected = {"unique_repo_name": "Repository with name `{}` already exists".format(fork_name)} assert_error(id_, expected, given=response.body) - @mock.patch.object(RepoModel, 'create_fork', crash) + @mock.patch.object(RepoModel, "create_fork", crash) def test_api_fork_repo_exception_occurred(self, backend): - source_name = backend['minimal'].repo_name + source_name = backend["minimal"].repo_name fork_name = backend.new_repo_name() id_, params = build_data( - self.apikey, 'fork_repo', - repoid=source_name, - fork_name=fork_name, - owner=TEST_USER_ADMIN_LOGIN) + self.apikey, "fork_repo", repoid=source_name, fork_name=fork_name, owner=TEST_USER_ADMIN_LOGIN + ) response = api_call(self.app, params) - expected = 'failed to fork repository `%s` as `%s`' % (source_name, - fork_name) + expected = "failed to fork repository `%s` as `%s`" % (source_name, fork_name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_fts_search.py b/rhodecode/api/tests/test_fts_search.py index 4dd5b810..bec86200 100644 --- a/rhodecode/api/tests/test_fts_search.py +++ b/rhodecode/api/tests/test_fts_search.py @@ -18,96 +18,111 @@ import pytest from rhodecode.tests import HG_REPO -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestApiSearch(object): - - @pytest.mark.parametrize("sort_dir", [ - "asc", - "desc", - ]) - @pytest.mark.parametrize("sort", [ - "xxx", - "author_email", - "date", - "message", - ]) - @pytest.mark.parametrize("query, expected_hits, expected_paths", [ - ('todo', 23, [ - 'vcs/backends/hg/inmemory.py', - 'vcs/tests/test_git.py']), - ('extension:rst installation', 6, [ - 'docs/index.rst', - 'docs/installation.rst']), - ('def repo', 87, [ - 'vcs/tests/test_git.py', - 'vcs/tests/test_changesets.py']), - ('repository:%s def test' % HG_REPO, 18, [ - 'vcs/tests/test_git.py', - 'vcs/tests/test_changesets.py']), - ('"def main"', 9, [ - 'vcs/__init__.py', - 'vcs/tests/__init__.py', - 'vcs/utils/progressbar.py']), - ('owner:test_admin', 358, [ - 'vcs/tests/base.py', - 'MANIFEST.in', - 'vcs/utils/termcolors.py', - 'docs/theme/ADC/static/documentation.png']), - ('owner:test_admin def main', 72, [ - 'vcs/__init__.py', - 'vcs/tests/test_utils_filesize.py', - 'vcs/tests/test_cli.py']), - ('owner:michał test', 0, []), - ]) + @pytest.mark.parametrize( + "sort_dir", + [ + "asc", + "desc", + ], + ) + @pytest.mark.parametrize( + "sort", + [ + "xxx", + "author_email", + "date", + "message", + ], + ) + @pytest.mark.parametrize( + "query, expected_hits, expected_paths", + [ + ("todo", 23, ["vcs/backends/hg/inmemory.py", "vcs/tests/test_git.py"]), + ("extension:rst installation", 6, ["docs/index.rst", "docs/installation.rst"]), + ("def repo", 87, ["vcs/tests/test_git.py", "vcs/tests/test_changesets.py"]), + ("repository:%s def test" % HG_REPO, 18, ["vcs/tests/test_git.py", "vcs/tests/test_changesets.py"]), + ('"def main"', 9, ["vcs/__init__.py", "vcs/tests/__init__.py", "vcs/utils/progressbar.py"]), + ( + "owner:test_admin", + 358, + [ + "vcs/tests/base.py", + "MANIFEST.in", + "vcs/utils/termcolors.py", + "docs/theme/ADC/static/documentation.png", + ], + ), + ( + "owner:test_admin def main", + 72, + ["vcs/__init__.py", "vcs/tests/test_utils_filesize.py", "vcs/tests/test_cli.py"], + ), + ("owner:michał test", 0, []), + ], + ) def test_search_content_results(self, sort_dir, sort, query, expected_hits, expected_paths): id_, params = build_data( - self.apikey_regular, 'search', + self.apikey_regular, + "search", search_query=query, - search_sort='{}:{}'.format(sort_dir, sort), - search_type='content') + search_sort="{}:{}".format(sort_dir, sort), + search_type="content", + ) response = api_call(self.app, params) json_response = response.json - assert json_response['result']['item_count'] == expected_hits - paths = [x['f_path'] for x in json_response['result']['results']] + assert json_response["result"]["item_count"] == expected_hits + paths = [x["f_path"] for x in json_response["result"]["results"]] for expected_path in expected_paths: assert expected_path in paths - @pytest.mark.parametrize("sort_dir", [ - "asc", - "desc", - ]) - @pytest.mark.parametrize("sort", [ - "xxx", - "date", - "file", - "size", - ]) - @pytest.mark.parametrize("query, expected_hits, expected_paths", [ - ('readme.rst', 3, []), - ('test*', 75, []), - ('*model*', 1, []), - ('extension:rst', 48, []), - ('extension:rst api', 24, []), - ]) + @pytest.mark.parametrize( + "sort_dir", + [ + "asc", + "desc", + ], + ) + @pytest.mark.parametrize( + "sort", + [ + "xxx", + "date", + "file", + "size", + ], + ) + @pytest.mark.parametrize( + "query, expected_hits, expected_paths", + [ + ("readme.rst", 3, []), + ("test*", 75, []), + ("*model*", 1, []), + ("extension:rst", 48, []), + ("extension:rst api", 24, []), + ], + ) def test_search_file_paths(self, sort_dir, sort, query, expected_hits, expected_paths): id_, params = build_data( - self.apikey_regular, 'search', + self.apikey_regular, + "search", search_query=query, - search_sort='{}:{}'.format(sort_dir, sort), - search_type='path') + search_sort="{}:{}".format(sort_dir, sort), + search_type="path", + ) response = api_call(self.app, params) json_response = response.json - assert json_response['result']['item_count'] == expected_hits - paths = [x['f_path'] for x in json_response['result']['results']] + assert json_response["result"]["item_count"] == expected_hits + paths = [x["f_path"] for x in json_response["result"]["results"]] for expected_path in expected_paths: assert expected_path in paths diff --git a/rhodecode/api/tests/test_get_gist.py b/rhodecode/api/tests/test_get_gist.py index 77f63a1d..17bbe5ee 100644 --- a/rhodecode/api/tests/test_get_gist.py +++ b/rhodecode/api/tests/test_get_gist.py @@ -21,8 +21,7 @@ import pytest from rhodecode.lib.str_utils import safe_bytes from rhodecode.model.db import Gist -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") @@ -33,68 +32,81 @@ class TestApiGetGist(object): gist_created_on = gist.created_on gist_modified_at = gist.modified_at id_, params = build_data( - self.apikey, 'get_gist', gistid=gist_id, ) + self.apikey, + "get_gist", + gistid=gist_id, + ) response = api_call(self.app, params) expected = { - 'access_id': gist_id, - 'created_on': gist_created_on, - 'modified_at': gist_modified_at, - 'description': 'new-gist', - 'expires': -1.0, - 'gist_id': int(gist_id), - 'type': 'public', - 'url': 'http://%s/_admin/gists/%s' % (http_host_only_stub, gist_id,), - 'acl_level': Gist.ACL_LEVEL_PUBLIC, - 'content': None, + "access_id": gist_id, + "created_on": gist_created_on, + "modified_at": gist_modified_at, + "description": "new-gist", + "expires": -1.0, + "gist_id": int(gist_id), + "type": "public", + "url": "http://%s/_admin/gists/%s" + % ( + http_host_only_stub, + gist_id, + ), + "acl_level": Gist.ACL_LEVEL_PUBLIC, + "content": None, } assert_ok(id_, expected, given=response.body) def test_api_get_gist_with_content(self, gist_util, http_host_only_stub): mapping = { - b'filename1.txt': {'content': b'hello world'}, - safe_bytes('filename1ą.txt'): {'content': safe_bytes('hello worldę')} + b"filename1.txt": {"content": b"hello world"}, + safe_bytes("filename1ą.txt"): {"content": safe_bytes("hello worldę")}, } gist = gist_util.create_gist(gist_mapping=mapping) gist_id = gist.gist_access_id gist_created_on = gist.created_on gist_modified_at = gist.modified_at - id_, params = build_data( - self.apikey, 'get_gist', gistid=gist_id, content=True) + id_, params = build_data(self.apikey, "get_gist", gistid=gist_id, content=True) response = api_call(self.app, params) expected = { - 'access_id': gist_id, - 'created_on': gist_created_on, - 'modified_at': gist_modified_at, - 'description': 'new-gist', - 'expires': -1.0, - 'gist_id': int(gist_id), - 'type': 'public', - 'url': 'http://%s/_admin/gists/%s' % (http_host_only_stub, gist_id,), - 'acl_level': Gist.ACL_LEVEL_PUBLIC, - 'content': { - 'filename1.txt': 'hello world', - 'filename1ą.txt': 'hello worldę' - }, + "access_id": gist_id, + "created_on": gist_created_on, + "modified_at": gist_modified_at, + "description": "new-gist", + "expires": -1.0, + "gist_id": int(gist_id), + "type": "public", + "url": "http://%s/_admin/gists/%s" + % ( + http_host_only_stub, + gist_id, + ), + "acl_level": Gist.ACL_LEVEL_PUBLIC, + "content": {"filename1.txt": "hello world", "filename1ą.txt": "hello worldę"}, } assert_ok(id_, expected, given=response.body) def test_api_get_gist_not_existing(self): id_, params = build_data( - self.apikey_regular, 'get_gist', gistid='12345', ) + self.apikey_regular, + "get_gist", + gistid="12345", + ) response = api_call(self.app, params) - expected = 'gist `%s` does not exist' % ('12345',) + expected = "gist `%s` does not exist" % ("12345",) assert_error(id_, expected, given=response.body) def test_api_get_gist_private_gist_without_permission(self, gist_util): gist = gist_util.create_gist() gist_id = gist.gist_access_id id_, params = build_data( - self.apikey_regular, 'get_gist', gistid=gist_id, ) + self.apikey_regular, + "get_gist", + gistid=gist_id, + ) response = api_call(self.app, params) - expected = 'gist `%s` does not exist' % (gist_id,) + expected = "gist `%s` does not exist" % (gist_id,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_gists.py b/rhodecode/api/tests/test_get_gists.py index 7d17cfd3..077c51ec 100644 --- a/rhodecode/api/tests/test_get_gists.py +++ b/rhodecode/api/tests/test_get_gists.py @@ -20,8 +20,7 @@ import pytest from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_error @pytest.mark.usefixtures("testuser_api", "app") @@ -30,9 +29,9 @@ class TestApiGetGist(object): gist_util.create_gist() gist_util.create_gist() - id_, params = build_data(self.apikey, 'get_gists') + id_, params = build_data(self.apikey, "get_gists") response = api_call(self.app, params) - assert len(response.json['result']) == 2 + assert len(response.json["result"]) == 2 def test_api_get_gists_regular_user(self, gist_util): # by admin @@ -44,9 +43,9 @@ class TestApiGetGist(object): gist_util.create_gist(owner=self.TEST_USER_LOGIN) gist_util.create_gist(owner=self.TEST_USER_LOGIN) - id_, params = build_data(self.apikey_regular, 'get_gists') + id_, params = build_data(self.apikey_regular, "get_gists") response = api_call(self.app, params) - assert len(response.json['result']) == 3 + assert len(response.json["result"]) == 3 def test_api_get_gists_only_for_regular_user(self, gist_util): # by admin @@ -58,15 +57,12 @@ class TestApiGetGist(object): gist_util.create_gist(owner=self.TEST_USER_LOGIN) gist_util.create_gist(owner=self.TEST_USER_LOGIN) - id_, params = build_data( - self.apikey, 'get_gists', userid=self.TEST_USER_LOGIN) + id_, params = build_data(self.apikey, "get_gists", userid=self.TEST_USER_LOGIN) response = api_call(self.app, params) - assert len(response.json['result']) == 3 + assert len(response.json["result"]) == 3 def test_api_get_gists_regular_user_with_different_userid(self): - id_, params = build_data( - self.apikey_regular, 'get_gists', - userid=TEST_USER_ADMIN_LOGIN) + id_, params = build_data(self.apikey_regular, "get_gists", userid=TEST_USER_ADMIN_LOGIN) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_ip.py b/rhodecode/api/tests/test_get_ip.py index d071456c..a74cd122 100644 --- a/rhodecode/api/tests/test_get_ip.py +++ b/rhodecode/api/tests/test_get_ip.py @@ -25,10 +25,7 @@ from rhodecode.api.tests.utils import build_data, api_call, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestGetIp(object): def test_api_get_ip(self): - id_, params = build_data(self.apikey, 'get_ip') + id_, params = build_data(self.apikey, "get_ip") response = api_call(self.app, params) - expected = { - 'server_ip_addr': '0.0.0.0', - 'user_ips': [] - } + expected = {"server_ip_addr": "0.0.0.0", "user_ips": []} assert_ok(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_locks.py b/rhodecode/api/tests/test_get_locks.py index 944ae511..09882280 100644 --- a/rhodecode/api/tests/test_get_locks.py +++ b/rhodecode/api/tests/test_get_locks.py @@ -21,69 +21,62 @@ import pytest from rhodecode.model.db import Repository, User from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error @pytest.mark.usefixtures("testuser_api", "app") class TestGetLocks(object): def test_api_get_user_locks_regular_user(self): - id_, params = build_data(self.apikey_regular, 'get_user_locks') + id_, params = build_data(self.apikey_regular, "get_user_locks") response = api_call(self.app, params) expected = [] assert_ok(id_, expected, given=response.body) def test_api_get_user_locks_with_userid_regular_user(self): - id_, params = build_data( - self.apikey_regular, 'get_user_locks', userid=TEST_USER_ADMIN_LOGIN) + id_, params = build_data(self.apikey_regular, "get_user_locks", userid=TEST_USER_ADMIN_LOGIN) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) def test_api_get_user_locks(self): - id_, params = build_data(self.apikey, 'get_user_locks') + id_, params = build_data(self.apikey, "get_user_locks") response = api_call(self.app, params) expected = [] assert_ok(id_, expected, given=response.body) - @pytest.mark.parametrize("apikey_attr, expect_secrets", [ - ('apikey', True), - ('apikey_regular', False), - ]) - def test_api_get_user_locks_with_one_locked_repo( - self, apikey_attr, expect_secrets, backend): - + @pytest.mark.parametrize( + "apikey_attr, expect_secrets", + [ + ("apikey", True), + ("apikey_regular", False), + ], + ) + def test_api_get_user_locks_with_one_locked_repo(self, apikey_attr, expect_secrets, backend): repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN) - Repository.lock( - repo, User.get_by_username(self.TEST_USER_LOGIN).user_id) + Repository.lock(repo, User.get_by_username(self.TEST_USER_LOGIN).user_id) apikey = getattr(self, apikey_attr) - id_, params = build_data(apikey, 'get_user_locks') - if apikey_attr == 'apikey': + id_, params = build_data(apikey, "get_user_locks") + if apikey_attr == "apikey": # super-admin should call in specific user - id_, params = build_data(apikey, 'get_user_locks', - userid=self.TEST_USER_LOGIN) + id_, params = build_data(apikey, "get_user_locks", userid=self.TEST_USER_LOGIN) response = api_call(self.app, params) expected = [repo.get_api_data(include_secrets=expect_secrets)] assert_ok(id_, expected, given=response.body) - def test_api_get_user_locks_with_one_locked_repo_for_specific_user( - self, backend): + def test_api_get_user_locks_with_one_locked_repo_for_specific_user(self, backend): repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN) - Repository.lock(repo, User.get_by_username( - self.TEST_USER_LOGIN).user_id) - id_, params = build_data( - self.apikey, 'get_user_locks', userid=self.TEST_USER_LOGIN) + Repository.lock(repo, User.get_by_username(self.TEST_USER_LOGIN).user_id) + id_, params = build_data(self.apikey, "get_user_locks", userid=self.TEST_USER_LOGIN) response = api_call(self.app, params) expected = [repo.get_api_data(include_secrets=True)] assert_ok(id_, expected, given=response.body) def test_api_get_user_locks_with_userid(self): - id_, params = build_data( - self.apikey, 'get_user_locks', userid=TEST_USER_REGULAR_LOGIN) + id_, params = build_data(self.apikey, "get_user_locks", userid=TEST_USER_REGULAR_LOGIN) response = api_call(self.app, params) expected = [] assert_ok(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_method.py b/rhodecode/api/tests/test_get_method.py index 1f294252..f45f5e3d 100644 --- a/rhodecode/api/tests/test_get_method.py +++ b/rhodecode/api/tests/test_get_method.py @@ -25,37 +25,45 @@ from rhodecode.api.tests.utils import build_data, api_call, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestGetMethod(object): def test_get_methods_no_matches(self): - id_, params = build_data(self.apikey, 'get_method', pattern='hello') + id_, params = build_data(self.apikey, "get_method", pattern="hello") response = api_call(self.app, params) expected = [] assert_ok(id_, expected, given=response.body) def test_get_methods(self): - id_, params = build_data(self.apikey, 'get_method', pattern='*comment*') + id_, params = build_data(self.apikey, "get_method", pattern="*comment*") response = api_call(self.app, params) expected = [ - 'changeset_comment', 'comment_pull_request', 'get_pull_request_comments', - 'comment_commit', 'edit_comment', 'get_comment', 'get_repo_comments' + "changeset_comment", + "comment_pull_request", + "get_pull_request_comments", + "comment_commit", + "edit_comment", + "get_comment", + "get_repo_comments", ] assert_ok(id_, expected, given=response.body) def test_get_methods_on_single_match(self): - id_, params = build_data(self.apikey, 'get_method', - pattern='*comment_commit*') + id_, params = build_data(self.apikey, "get_method", pattern="*comment_commit*") response = api_call(self.app, params) - expected = ['comment_commit', - {'apiuser': '', - 'comment_type': "", - 'commit_id': '', - 'extra_recipients': '', - 'message': '', - 'repoid': '', - 'request': '', - 'resolves_comment_id': '', - 'status': '', - 'userid': '>', - 'send_email': ''}] + expected = [ + "comment_commit", + { + "apiuser": "", + "comment_type": "", + "commit_id": "", + "extra_recipients": "", + "message": "", + "repoid": "", + "request": "", + "resolves_comment_id": "", + "status": "", + "userid": ">", + "send_email": "", + }, + ] assert_ok(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_pull_request.py b/rhodecode/api/tests/test_get_pull_request.py index 753e1926..0889bb65 100644 --- a/rhodecode/api/tests/test_get_pull_request.py +++ b/rhodecode/api/tests/test_get_pull_request.py @@ -20,8 +20,7 @@ import pytest import urlobject -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok from rhodecode.lib import helpers as h from rhodecode.lib.str_utils import safe_str @@ -31,112 +30,104 @@ pytestmark = pytest.mark.backends("git", "hg") @pytest.mark.usefixtures("testuser_api", "app") class TestGetPullRequest(object): - def test_api_get_pull_request(self, pr_util, http_host_only_stub): from rhodecode.model.pull_request import PullRequestModel + pull_request = pr_util.create_pull_request(mergeable=True) id_, params = build_data( - self.apikey, 'get_pull_request', - pullrequestid=pull_request.pull_request_id, merge_state=True) + self.apikey, "get_pull_request", pullrequestid=pull_request.pull_request_id, merge_state=True + ) response = api_call(self.app, params) - assert response.status == '200 OK' + assert response.status == "200 OK" url_obj = urlobject.URLObject( h.route_url( - 'pullrequest_show', + "pullrequest_show", repo_name=pull_request.target_repo.repo_name, - pull_request_id=pull_request.pull_request_id)) + pull_request_id=pull_request.pull_request_id, + ) + ) - pr_url = safe_str( - url_obj.with_netloc(http_host_only_stub)) - source_url = safe_str( - pull_request.source_repo.clone_url().with_netloc(http_host_only_stub)) - target_url = safe_str( - pull_request.target_repo.clone_url().with_netloc(http_host_only_stub)) - shadow_url = safe_str( - PullRequestModel().get_shadow_clone_url(pull_request)) + pr_url = safe_str(url_obj.with_netloc(http_host_only_stub)) + source_url = safe_str(pull_request.source_repo.clone_url().with_netloc(http_host_only_stub)) + target_url = safe_str(pull_request.target_repo.clone_url().with_netloc(http_host_only_stub)) + shadow_url = safe_str(PullRequestModel().get_shadow_clone_url(pull_request)) expected = { - 'pull_request_id': pull_request.pull_request_id, - 'url': pr_url, - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'state': pull_request.pull_request_state, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': True, - 'message': 'This pull request can be automatically merged.', + "pull_request_id": pull_request.pull_request_id, + "url": pr_url, + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "state": pull_request.pull_request_state, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": True, + "message": "This pull request can be automatically merged.", }, - 'source': { - 'clone_url': source_url, - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": source_url, + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': target_url, - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": target_url, + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': { - 'clone_url': shadow_url, - 'reference': { - 'name': pull_request.shadow_merge_ref.name, - 'type': pull_request.shadow_merge_ref.type, - 'commit_id': pull_request.shadow_merge_ref.commit_id, + "merge": { + "clone_url": shadow_url, + "reference": { + "name": pull_request.shadow_merge_ref.name, + "type": pull_request.shadow_merge_ref.type, + "commit_id": pull_request.shadow_merge_ref.commit_id, }, }, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } assert_ok(id_, expected, response.body) def test_api_get_pull_request_repo_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'get_pull_request', - repoid=666, pullrequestid=pull_request.pull_request_id) + self.apikey, "get_pull_request", repoid=666, pullrequestid=pull_request.pull_request_id + ) response = api_call(self.app, params) - expected = 'repository `666` does not exist' + expected = "repository `666` does not exist" assert_error(id_, expected, given=response.body) def test_api_get_pull_request_pull_request_error(self): - id_, params = build_data( - self.apikey, 'get_pull_request', pullrequestid=666) + id_, params = build_data(self.apikey, "get_pull_request", pullrequestid=666) response = api_call(self.app, params) - expected = 'pull request `666` does not exist' + expected = "pull request `666` does not exist" assert_error(id_, expected, given=response.body) def test_api_get_pull_request_pull_request_error_just_pr_id(self): - id_, params = build_data( - self.apikey, 'get_pull_request', - pullrequestid=666) + id_, params = build_data(self.apikey, "get_pull_request", pullrequestid=666) response = api_call(self.app, params) - expected = 'pull request `666` does not exist' + expected = "pull request `666` does not exist" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_pull_request_comments.py b/rhodecode/api/tests/test_get_pull_request_comments.py index d9378185..2a271fdb 100644 --- a/rhodecode/api/tests/test_get_pull_request_comments.py +++ b/rhodecode/api/tests/test_get_pull_request_comments.py @@ -19,64 +19,61 @@ import pytest -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok pytestmark = pytest.mark.backends("git", "hg") @pytest.mark.usefixtures("testuser_api", "app") class TestGetPullRequestComments(object): - def test_api_get_pull_request_comments(self, pr_util, http_host_only_stub): from rhodecode.model.pull_request import PullRequestModel pull_request = pr_util.create_pull_request(mergeable=True) - id_, params = build_data( - self.apikey, 'get_pull_request_comments', - pullrequestid=pull_request.pull_request_id) + id_, params = build_data(self.apikey, "get_pull_request_comments", pullrequestid=pull_request.pull_request_id) response = api_call(self.app, params) - assert response.status == '200 OK' - resp_date = response.json['result'][0]['comment_created_on'] - resp_comment_id = response.json['result'][0]['comment_id'] + assert response.status == "200 OK" + resp_date = response.json["result"][0]["comment_created_on"] + resp_comment_id = response.json["result"][0]["comment_id"] expected = [ - {'comment_author': {'active': True, - 'full_name_or_username': 'RhodeCode Admin', - 'username': 'test_admin'}, - 'comment_created_on': resp_date, - 'comment_f_path': None, - 'comment_id': resp_comment_id, - 'comment_lineno': None, - 'comment_status': {'status': 'under_review', - 'status_lbl': 'Under Review'}, - 'comment_text': 'Auto status change to |new_status|\n\n.. |new_status| replace:: *"Under Review"*', - 'comment_type': 'note', - 'comment_resolved_by': None, - 'pull_request_version': None, - 'comment_last_version': 0, - 'comment_commit_id': None, - 'comment_pull_request_id': pull_request.pull_request_id - } + { + "comment_author": { + "active": True, + "full_name_or_username": "RhodeCode Admin", + "username": "test_admin", + }, + "comment_created_on": resp_date, + "comment_f_path": None, + "comment_id": resp_comment_id, + "comment_lineno": None, + "comment_status": {"status": "under_review", "status_lbl": "Under Review"}, + "comment_text": 'Auto status change to |new_status|\n\n.. |new_status| replace:: *"Under Review"*', + "comment_type": "note", + "comment_resolved_by": None, + "pull_request_version": None, + "comment_last_version": 0, + "comment_commit_id": None, + "comment_pull_request_id": pull_request.pull_request_id, + } ] assert_ok(id_, expected, response.body) def test_api_get_pull_request_comments_repo_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'get_pull_request_comments', - repoid=666, pullrequestid=pull_request.pull_request_id) + self.apikey, "get_pull_request_comments", repoid=666, pullrequestid=pull_request.pull_request_id + ) response = api_call(self.app, params) - expected = 'repository `666` does not exist' + expected = "repository `666` does not exist" assert_error(id_, expected, given=response.body) def test_api_get_pull_request_comments_pull_request_error(self): - id_, params = build_data( - self.apikey, 'get_pull_request_comments', pullrequestid=666) + id_, params = build_data(self.apikey, "get_pull_request_comments", pullrequestid=666) response = api_call(self.app, params) - expected = 'pull request `666` does not exist' + expected = "pull request `666` does not exist" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_pull_requests.py b/rhodecode/api/tests/test_get_pull_requests.py index ab3dda82..dc42631f 100644 --- a/rhodecode/api/tests/test_get_pull_requests.py +++ b/rhodecode/api/tests/test_get_pull_requests.py @@ -21,13 +21,11 @@ import pytest from rhodecode.model.meta import Session from rhodecode.model.pull_request import PullRequestModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_error @pytest.mark.usefixtures("testuser_api", "app") class TestGetPullRequest(object): - @pytest.mark.backends("git", "hg") def test_api_get_pull_requests(self, pr_util): pull_request = pr_util.create_pull_request() @@ -44,37 +42,32 @@ class TestGetPullRequest(object): description=pull_request.description, ) Session().commit() - id_, params = build_data( - self.apikey, 'get_pull_requests', - repoid=pull_request.target_repo.repo_name) + id_, params = build_data(self.apikey, "get_pull_requests", repoid=pull_request.target_repo.repo_name) response = api_call(self.app, params) - assert response.status == '200 OK' - assert len(response.json['result']) == 2 + assert response.status == "200 OK" + assert len(response.json["result"]) == 2 - PullRequestModel().close_pull_request( - pull_request_2, pull_request_2.author) + PullRequestModel().close_pull_request(pull_request_2, pull_request_2.author) Session().commit() id_, params = build_data( - self.apikey, 'get_pull_requests', - repoid=pull_request.target_repo.repo_name, - status='new') + self.apikey, "get_pull_requests", repoid=pull_request.target_repo.repo_name, status="new" + ) response = api_call(self.app, params) - assert response.status == '200 OK' - assert len(response.json['result']) == 1 + assert response.status == "200 OK" + assert len(response.json["result"]) == 1 id_, params = build_data( - self.apikey, 'get_pull_requests', - repoid=pull_request.target_repo.repo_name, - status='closed') + self.apikey, "get_pull_requests", repoid=pull_request.target_repo.repo_name, status="closed" + ) response = api_call(self.app, params) - assert response.status == '200 OK' - assert len(response.json['result']) == 1 + assert response.status == "200 OK" + assert len(response.json["result"]) == 1 @pytest.mark.backends("git", "hg") def test_api_get_pull_requests_repo_error(self): - id_, params = build_data(self.apikey, 'get_pull_requests', repoid=666) + id_, params = build_data(self.apikey, "get_pull_requests", repoid=666) response = api_call(self.app, params) - expected = 'repository `666` does not exist' + expected = "repository `666` does not exist" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_repo.py b/rhodecode/api/tests/test_get_repo.py index 42ee1ada..71bdaed8 100644 --- a/rhodecode/api/tests/test_get_repo.py +++ b/rhodecode/api/tests/test_get_repo.py @@ -23,39 +23,41 @@ from rhodecode.model.meta import Session from rhodecode.model.repo import RepoModel from rhodecode.model.user import UserModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, expected_permissions) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, expected_permissions @pytest.mark.usefixtures("testuser_api", "app") class TestGetRepo(object): - @pytest.mark.parametrize("apikey_attr, expect_secrets", [ - ('apikey', True), - ('apikey_regular', False), - ]) - @pytest.mark.parametrize("cache_param", [ - True, - False, - None, - ]) - def test_api_get_repo( - self, apikey_attr, expect_secrets, cache_param, backend, - user_util): + @pytest.mark.parametrize( + "apikey_attr, expect_secrets", + [ + ("apikey", True), + ("apikey_regular", False), + ], + ) + @pytest.mark.parametrize( + "cache_param", + [ + True, + False, + None, + ], + ) + def test_api_get_repo(self, apikey_attr, expect_secrets, cache_param, backend, user_util): repo = backend.create_repo() repo_id = repo.repo_id usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) group = user_util.create_user_group(members=[usr]) - user_util.grant_user_group_permission_to_repo( - repo=repo, user_group=group, permission_name='repository.read') + user_util.grant_user_group_permission_to_repo(repo=repo, user_group=group, permission_name="repository.read") Session().commit() kwargs = { - 'repoid': repo.repo_name, + "repoid": repo.repo_name, } if cache_param is not None: - kwargs['cache'] = cache_param + kwargs["cache"] = cache_param apikey = getattr(self, apikey_attr) - id_, params = build_data(apikey, 'get_repo', **kwargs) + id_, params = build_data(apikey, "get_repo", **kwargs) response = api_call(self.app, params) ret = repo.get_api_data() @@ -66,21 +68,23 @@ class TestGetRepo(object): repo = RepoModel().get(repo_id) for user in repo.followers: - followers.append(user.user.get_api_data( - include_secrets=expect_secrets)) + followers.append(user.user.get_api_data(include_secrets=expect_secrets)) - ret['permissions'] = permissions - ret['followers'] = followers + ret["permissions"] = permissions + ret["followers"] = followers expected = ret assert_ok(id_, expected, given=response.body) - @pytest.mark.parametrize("grant_perm", [ - 'repository.admin', - 'repository.write', - 'repository.read', - ]) + @pytest.mark.parametrize( + "grant_perm", + [ + "repository.admin", + "repository.write", + "repository.read", + ], + ) def test_api_get_repo_by_non_admin(self, grant_perm, backend): # TODO: Depending on which tests are running before this one, we # start with a different number of permissions in the database. @@ -88,12 +92,9 @@ class TestGetRepo(object): repo_id = repo.repo_id permission_count = len(repo.repo_to_perm) - RepoModel().grant_user_permission(repo=backend.repo_name, - user=self.TEST_USER_LOGIN, - perm=grant_perm) + RepoModel().grant_user_permission(repo=backend.repo_name, user=self.TEST_USER_LOGIN, perm=grant_perm) Session().commit() - id_, params = build_data( - self.apikey_regular, 'get_repo', repoid=backend.repo_name) + id_, params = build_data(self.apikey_regular, "get_repo", repoid=backend.repo_name) response = api_call(self.app, params) repo = RepoModel().get_by_repo_name(backend.repo_name) @@ -109,33 +110,28 @@ class TestGetRepo(object): for user in repo.followers: followers.append(user.user.get_api_data()) - ret['permissions'] = permissions - ret['followers'] = followers + ret["permissions"] = permissions + ret["followers"] = followers expected = ret try: assert_ok(id_, expected, given=response.body) finally: - RepoModel().revoke_user_permission( - backend.repo_name, self.TEST_USER_LOGIN) + RepoModel().revoke_user_permission(backend.repo_name, self.TEST_USER_LOGIN) def test_api_get_repo_by_non_admin_no_permission_to_repo(self, backend): - RepoModel().grant_user_permission(repo=backend.repo_name, - user=self.TEST_USER_LOGIN, - perm='repository.none') + RepoModel().grant_user_permission(repo=backend.repo_name, user=self.TEST_USER_LOGIN, perm="repository.none") - id_, params = build_data( - self.apikey_regular, 'get_repo', repoid=backend.repo_name) + id_, params = build_data(self.apikey_regular, "get_repo", repoid=backend.repo_name) response = api_call(self.app, params) - expected = 'repository `%s` does not exist' % (backend.repo_name) + expected = "repository `%s` does not exist" % (backend.repo_name) assert_error(id_, expected, given=response.body) def test_api_get_repo_not_existing(self): - id_, params = build_data( - self.apikey, 'get_repo', repoid='no-such-repo') + id_, params = build_data(self.apikey, "get_repo", repoid="no-such-repo") response = api_call(self.app, params) - ret = 'repository `%s` does not exist' % 'no-such-repo' + ret = "repository `%s` does not exist" % "no-such-repo" expected = ret assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_repo_changeset.py b/rhodecode/api/tests/test_get_repo_changeset.py index 51cb20bb..36580ad1 100644 --- a/rhodecode/api/tests/test_get_repo_changeset.py +++ b/rhodecode/api/tests/test_get_repo_changeset.py @@ -24,90 +24,102 @@ from rhodecode.api.tests.utils import build_data, api_call, assert_error @pytest.mark.usefixtures("testuser_api", "app") class TestGetRepoChangeset(object): - @pytest.mark.parametrize("details", ['basic', 'extended', 'full']) + @pytest.mark.parametrize("details", ["basic", "extended", "full"]) def test_get_repo_changeset(self, details, backend): commit = backend.repo.get_commit(commit_idx=0) __, params = build_data( - self.apikey, 'get_repo_changeset', - repoid=backend.repo_name, revision=commit.raw_id, + self.apikey, + "get_repo_changeset", + repoid=backend.repo_name, + revision=commit.raw_id, details=details, ) response = api_call(self.app, params) - result = response.json['result'] - assert result['revision'] == 0 - assert result['raw_id'] == commit.raw_id + result = response.json["result"] + assert result["revision"] == 0 + assert result["raw_id"] == commit.raw_id - if details == 'full': - assert result['refs']['bookmarks'] == getattr( - commit, 'bookmarks', []) + if details == "full": + assert result["refs"]["bookmarks"] == getattr(commit, "bookmarks", []) branches = [commit.branch] if commit.branch else [] - assert result['refs']['branches'] == branches - assert result['refs']['tags'] == commit.tags + assert result["refs"]["branches"] == branches + assert result["refs"]["tags"] == commit.tags - @pytest.mark.parametrize("details", ['basic', 'extended', 'full']) + @pytest.mark.parametrize("details", ["basic", "extended", "full"]) def test_get_repo_changeset_bad_type(self, details, backend): id_, params = build_data( - self.apikey, 'get_repo_changeset', - repoid=backend.repo_name, revision=0, + self.apikey, + "get_repo_changeset", + repoid=backend.repo_name, + revision=0, details=details, ) response = api_call(self.app, params) expected = "commit_id must be a string value got instead" assert_error(id_, expected, given=response.body) - @pytest.mark.parametrize("details", ['basic', 'extended', 'full']) + @pytest.mark.parametrize("details", ["basic", "extended", "full"]) def test_get_repo_changesets(self, details, backend): limit = 2 commit = backend.repo.get_commit(commit_idx=0) __, params = build_data( - self.apikey, 'get_repo_changesets', - repoid=backend.repo_name, start_rev=commit.raw_id, limit=limit, + self.apikey, + "get_repo_changesets", + repoid=backend.repo_name, + start_rev=commit.raw_id, + limit=limit, details=details, ) response = api_call(self.app, params) - result = response.json['result'] + result = response.json["result"] assert result assert len(result) == limit for x in range(limit): - assert result[x]['revision'] == x + assert result[x]["revision"] == x - if details == 'full': + if details == "full": for x in range(limit): - assert 'bookmarks' in result[x]['refs'] - assert 'branches' in result[x]['refs'] - assert 'tags' in result[x]['refs'] + assert "bookmarks" in result[x]["refs"] + assert "branches" in result[x]["refs"] + assert "tags" in result[x]["refs"] - @pytest.mark.parametrize("details", ['basic', 'extended', 'full']) - @pytest.mark.parametrize("start_rev, expected_revision", [ - ("0", 0), - ("10", 10), - ("20", 20), - ]) + @pytest.mark.parametrize("details", ["basic", "extended", "full"]) + @pytest.mark.parametrize( + "start_rev, expected_revision", + [ + ("0", 0), + ("10", 10), + ("20", 20), + ], + ) @pytest.mark.backends("hg", "git") - def test_get_repo_changesets_commit_range( - self, details, backend, start_rev, expected_revision): + def test_get_repo_changesets_commit_range(self, details, backend, start_rev, expected_revision): limit = 10 __, params = build_data( - self.apikey, 'get_repo_changesets', - repoid=backend.repo_name, start_rev=start_rev, limit=limit, + self.apikey, + "get_repo_changesets", + repoid=backend.repo_name, + start_rev=start_rev, + limit=limit, details=details, ) response = api_call(self.app, params) - result = response.json['result'] + result = response.json["result"] assert result assert len(result) == limit for i in range(limit): - assert result[i]['revision'] == int(expected_revision) + i - - @pytest.mark.parametrize("details", ['basic', 'extended', 'full']) - @pytest.mark.parametrize("start_rev, expected_revision", [ - ("0", 0), - ("10", 9), - ("20", 19), - ]) - def test_get_repo_changesets_commit_range_svn( - self, details, backend_svn, start_rev, expected_revision): + assert result[i]["revision"] == int(expected_revision) + i + @pytest.mark.parametrize("details", ["basic", "extended", "full"]) + @pytest.mark.parametrize( + "start_rev, expected_revision", + [ + ("0", 0), + ("10", 9), + ("20", 19), + ], + ) + def test_get_repo_changesets_commit_range_svn(self, details, backend_svn, start_rev, expected_revision): # TODO: johbo: SVN showed a problem here: The parameter "start_rev" # in our API allows to pass in a "Commit ID" as well as a # "Commit Index". In the case of Subversion it is not possible to @@ -116,22 +128,28 @@ class TestGetRepoChangeset(object): limit = 10 __, params = build_data( - self.apikey, 'get_repo_changesets', - repoid=backend_svn.repo_name, start_rev=start_rev, limit=limit, + self.apikey, + "get_repo_changesets", + repoid=backend_svn.repo_name, + start_rev=start_rev, + limit=limit, details=details, ) response = api_call(self.app, params) - result = response.json['result'] + result = response.json["result"] assert result assert len(result) == limit for i in range(limit): - assert result[i]['revision'] == int(expected_revision) + i + assert result[i]["revision"] == int(expected_revision) + i - @pytest.mark.parametrize("details", ['basic', 'extended', 'full']) + @pytest.mark.parametrize("details", ["basic", "extended", "full"]) def test_get_repo_changesets_bad_type(self, details, backend): id_, params = build_data( - self.apikey, 'get_repo_changesets', - repoid=backend.repo_name, start_rev=0, limit=2, + self.apikey, + "get_repo_changesets", + repoid=backend.repo_name, + start_rev=0, + limit=2, details=details, ) response = api_call(self.app, params) diff --git a/rhodecode/api/tests/test_get_repo_comments.py b/rhodecode/api/tests/test_get_repo_comments.py index 09375f4c..ba6e075b 100644 --- a/rhodecode/api/tests/test_get_repo_comments.py +++ b/rhodecode/api/tests/test_get_repo_comments.py @@ -23,15 +23,12 @@ from rhodecode.lib.str_utils import safe_str from rhodecode.model.db import User, ChangesetComment from rhodecode.model.meta import Session from rhodecode.model.comment import CommentsModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_call_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_call_ok @pytest.fixture() def make_repo_comments_factory(request): - class Make(object): - def make_comments(self, repo): user = User.get_first_super_admin() commit = repo.scm_instance()[0] @@ -42,22 +39,39 @@ def make_repo_comments_factory(request): # general comment = CommentsModel().create( - text='General Comment', repo=repo, user=user, commit_id=commit_id, - comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False) + text="General Comment", + repo=repo, + user=user, + commit_id=commit_id, + comment_type=ChangesetComment.COMMENT_TYPE_NOTE, + send_email=False, + ) comments.append(comment) # inline comment = CommentsModel().create( - text='Inline Comment', repo=repo, user=user, commit_id=commit_id, - f_path=file_0, line_no='n1', - comment_type=ChangesetComment.COMMENT_TYPE_NOTE, send_email=False) + text="Inline Comment", + repo=repo, + user=user, + commit_id=commit_id, + f_path=file_0, + line_no="n1", + comment_type=ChangesetComment.COMMENT_TYPE_NOTE, + send_email=False, + ) comments.append(comment) # todo comment = CommentsModel().create( - text='INLINE TODO Comment', repo=repo, user=user, commit_id=commit_id, - f_path=file_0, line_no='n1', - comment_type=ChangesetComment.COMMENT_TYPE_TODO, send_email=False) + text="INLINE TODO Comment", + repo=repo, + user=user, + commit_id=commit_id, + f_path=file_0, + line_no="n1", + comment_type=ChangesetComment.COMMENT_TYPE_TODO, + send_email=False, + ) comments.append(comment) return comments @@ -67,50 +81,51 @@ def make_repo_comments_factory(request): @pytest.mark.usefixtures("testuser_api", "app") class TestGetRepo(object): - - @pytest.mark.parametrize('filters, expected_count', [ - ({}, 3), - ({'comment_type': ChangesetComment.COMMENT_TYPE_NOTE}, 2), - ({'comment_type': ChangesetComment.COMMENT_TYPE_TODO}, 1), - ({'commit_id': 'FILLED DYNAMIC'}, 3), - ]) - def test_api_get_repo_comments(self, backend, user_util, - make_repo_comments_factory, filters, expected_count): - commits = [{'message': 'A'}, {'message': 'B'}] + @pytest.mark.parametrize( + "filters, expected_count", + [ + ({}, 3), + ({"comment_type": ChangesetComment.COMMENT_TYPE_NOTE}, 2), + ({"comment_type": ChangesetComment.COMMENT_TYPE_TODO}, 1), + ({"commit_id": "FILLED DYNAMIC"}, 3), + ], + ) + def test_api_get_repo_comments(self, backend, user_util, make_repo_comments_factory, filters, expected_count): + commits = [{"message": "A"}, {"message": "B"}] repo = backend.create_repo(commits=commits) make_repo_comments_factory.make_comments(repo) - api_call_params = {'repoid': repo.repo_name,} + api_call_params = { + "repoid": repo.repo_name, + } api_call_params.update(filters) - if 'commit_id' in api_call_params: + if "commit_id" in api_call_params: commit = repo.scm_instance()[0] commit_id = commit.raw_id - api_call_params['commit_id'] = commit_id + api_call_params["commit_id"] = commit_id - id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params) + id_, params = build_data(self.apikey, "get_repo_comments", **api_call_params) response = api_call(self.app, params) result = assert_call_ok(id_, given=response.body) assert len(result) == expected_count - def test_api_get_repo_comments_wrong_comment_type( - self, make_repo_comments_factory, backend_hg): - commits = [{'message': 'A'}, {'message': 'B'}] + def test_api_get_repo_comments_wrong_comment_type(self, make_repo_comments_factory, backend_hg): + commits = [{"message": "A"}, {"message": "B"}] repo = backend_hg.create_repo(commits=commits) make_repo_comments_factory.make_comments(repo) - api_call_params = {'repoid': repo.repo_name} - api_call_params.update({'comment_type': 'bogus'}) + api_call_params = {"repoid": repo.repo_name} + api_call_params.update({"comment_type": "bogus"}) - expected = 'comment_type must be one of `{}` got {}'.format( - ChangesetComment.COMMENT_TYPES, 'bogus') - id_, params = build_data(self.apikey, 'get_repo_comments', **api_call_params) + expected = "comment_type must be one of `{}` got {}".format(ChangesetComment.COMMENT_TYPES, "bogus") + id_, params = build_data(self.apikey, "get_repo_comments", **api_call_params) response = api_call(self.app, params) assert_error(id_, expected, given=response.body) def test_api_get_comment(self, make_repo_comments_factory, backend_hg): - commits = [{'message': 'A'}, {'message': 'B'}] + commits = [{"message": "A"}, {"message": "B"}] repo = backend_hg.create_repo(commits=commits) comments = make_repo_comments_factory.make_comments(repo) @@ -118,24 +133,20 @@ class TestGetRepo(object): Session().commit() for comment_id in comment_ids: - id_, params = build_data(self.apikey, 'get_comment', - **{'comment_id': comment_id}) + id_, params = build_data(self.apikey, "get_comment", **{"comment_id": comment_id}) response = api_call(self.app, params) result = assert_call_ok(id_, given=response.body) - assert result['comment_id'] == comment_id + assert result["comment_id"] == comment_id def test_api_get_comment_no_access(self, make_repo_comments_factory, backend_hg, user_util): - commits = [{'message': 'A'}, {'message': 'B'}] + commits = [{"message": "A"}, {"message": "B"}] repo = backend_hg.create_repo(commits=commits) comments = make_repo_comments_factory.make_comments(repo) comment_id = comments[0].comment_id test_user = user_util.create_user() - user_util.grant_user_permission_to_repo(repo, test_user, 'repository.none') + user_util.grant_user_permission_to_repo(repo, test_user, "repository.none") - id_, params = build_data(test_user.api_key, 'get_comment', - **{'comment_id': comment_id}) + id_, params = build_data(test_user.api_key, "get_comment", **{"comment_id": comment_id}) response = api_call(self.app, params) - assert_error(id_, - expected='comment `{}` does not exist'.format(comment_id), - given=response.body) + assert_error(id_, expected="comment `{}` does not exist".format(comment_id), given=response.body) diff --git a/rhodecode/api/tests/test_get_repo_group.py b/rhodecode/api/tests/test_get_repo_group.py index ccd8b4f6..e427d07c 100644 --- a/rhodecode/api/tests/test_get_repo_group.py +++ b/rhodecode/api/tests/test_get_repo_group.py @@ -20,8 +20,7 @@ import pytest from rhodecode.model.repo_group import RepoGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, expected_permissions) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, expected_permissions @pytest.mark.usefixtures("testuser_api", "app") @@ -30,8 +29,7 @@ class TestApiGetRepoGroup(object): repo_group = user_util.create_repo_group() repo_group_name = repo_group.group_name - id_, params = build_data( - self.apikey, 'get_repo_group', repogroupid=repo_group_name) + id_, params = build_data(self.apikey, "get_repo_group", repogroupid=repo_group_name) response = api_call(self.app, params) repo_group = RepoGroupModel()._get_repo_group(repo_group_name) @@ -39,15 +37,14 @@ class TestApiGetRepoGroup(object): permissions = expected_permissions(repo_group) - ret['permissions'] = permissions + ret["permissions"] = permissions expected = ret assert_ok(id_, expected, given=response.body) def test_api_get_repo_group_not_existing(self): - id_, params = build_data( - self.apikey, 'get_repo_group', repogroupid='no-such-repo-group') + id_, params = build_data(self.apikey, "get_repo_group", repogroupid="no-such-repo-group") response = api_call(self.app, params) - ret = 'repository group `%s` does not exist' % 'no-such-repo-group' + ret = "repository group `%s` does not exist" % "no-such-repo-group" expected = ret assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_repo_groups.py b/rhodecode/api/tests/test_get_repo_groups.py index b34c0bae..cb1a858c 100644 --- a/rhodecode/api/tests/test_get_repo_groups.py +++ b/rhodecode/api/tests/test_get_repo_groups.py @@ -26,7 +26,7 @@ from rhodecode.api.tests.utils import build_data, api_call, assert_ok, jsonify @pytest.mark.usefixtures("testuser_api", "app") class TestApiGetRepoGroups(object): def test_api_get_repo_groups(self): - id_, params = build_data(self.apikey, 'get_repo_groups') + id_, params = build_data(self.apikey, "get_repo_groups") response = api_call(self.app, params) result = [] diff --git a/rhodecode/api/tests/test_get_repo_nodes.py b/rhodecode/api/tests/test_get_repo_nodes.py index d963fe8f..44b24416 100644 --- a/rhodecode/api/tests/test_get_repo_nodes.py +++ b/rhodecode/api/tests/test_get_repo_nodes.py @@ -21,120 +21,137 @@ import pytest from rhodecode.model.meta import Session from rhodecode.model.repo import RepoModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestGetRepoNodes(object): - @pytest.mark.parametrize("name, ret_type", [ - ('all', 'all'), - ('dirs', 'dirs'), - ('files', 'files'), - ]) + @pytest.mark.parametrize( + "name, ret_type", + [ + ("all", "all"), + ("dirs", "dirs"), + ("files", "files"), + ], + ) def test_api_get_repo_nodes(self, name, ret_type, backend): - commit_id = 'tip' - path = '/' + commit_id = "tip" + path = "/" id_, params = build_data( - self.apikey, 'get_repo_nodes', - repoid=backend.repo_name, revision=commit_id, + self.apikey, + "get_repo_nodes", + repoid=backend.repo_name, + revision=commit_id, root_path=path, - ret_type=ret_type) + ret_type=ret_type, + ) response = api_call(self.app, params) # we don't the actual return types here since it's tested somewhere # else - expected = response.json['result'] + expected = response.json["result"] assert_ok(id_, expected, given=response.body) def test_api_get_repo_nodes_bad_commits(self, backend): - commit_id = 'i-dont-exist' - path = '/' + commit_id = "i-dont-exist" + path = "/" id_, params = build_data( - self.apikey, 'get_repo_nodes', - repoid=backend.repo_name, revision=commit_id, - root_path=path, ) + self.apikey, + "get_repo_nodes", + repoid=backend.repo_name, + revision=commit_id, + root_path=path, + ) response = api_call(self.app, params) - expected = 'failed to get repo: `%s` nodes' % (backend.repo_name,) + expected = "failed to get repo: `%s` nodes" % (backend.repo_name,) assert_error(id_, expected, given=response.body) def test_api_get_repo_nodes_bad_path(self, backend): - commit_id = 'tip' - path = '/idontexits' + commit_id = "tip" + path = "/idontexits" id_, params = build_data( - self.apikey, 'get_repo_nodes', - repoid=backend.repo_name, revision=commit_id, - root_path=path, ) + self.apikey, + "get_repo_nodes", + repoid=backend.repo_name, + revision=commit_id, + root_path=path, + ) response = api_call(self.app, params) - expected = 'failed to get repo: `%s` nodes' % (backend.repo_name,) + expected = "failed to get repo: `%s` nodes" % (backend.repo_name,) assert_error(id_, expected, given=response.body) def test_api_get_repo_nodes_max_file_bytes(self, backend): - commit_id = 'tip' - path = '/' + commit_id = "tip" + path = "/" max_file_bytes = 500 id_, params = build_data( - self.apikey, 'get_repo_nodes', - repoid=backend.repo_name, revision=commit_id, details='full', - root_path=path) + self.apikey, "get_repo_nodes", repoid=backend.repo_name, revision=commit_id, details="full", root_path=path + ) response = api_call(self.app, params) - assert any(file['content'] and len(file['content']) > max_file_bytes - for file in response.json['result']) + assert any(file["content"] and len(file["content"]) > max_file_bytes for file in response.json["result"]) id_, params = build_data( - self.apikey, 'get_repo_nodes', - repoid=backend.repo_name, revision=commit_id, - root_path=path, details='full', - max_file_bytes=max_file_bytes) + self.apikey, + "get_repo_nodes", + repoid=backend.repo_name, + revision=commit_id, + root_path=path, + details="full", + max_file_bytes=max_file_bytes, + ) response = api_call(self.app, params) assert all( - file['content'] is None if file['size'] > max_file_bytes else True - for file in response.json['result']) + file["content"] is None if file["size"] > max_file_bytes else True for file in response.json["result"] + ) def test_api_get_repo_nodes_bad_ret_type(self, backend): - commit_id = 'tip' - path = '/' - ret_type = 'error' + commit_id = "tip" + path = "/" + ret_type = "error" id_, params = build_data( - self.apikey, 'get_repo_nodes', - repoid=backend.repo_name, revision=commit_id, + self.apikey, + "get_repo_nodes", + repoid=backend.repo_name, + revision=commit_id, root_path=path, - ret_type=ret_type) + ret_type=ret_type, + ) response = api_call(self.app, params) - expected = ('ret_type must be one of %s' - % (','.join(['all', 'dirs', 'files']))) + expected = "ret_type must be one of %s" % (",".join(["all", "dirs", "files"])) assert_error(id_, expected, given=response.body) - @pytest.mark.parametrize("name, ret_type, grant_perm", [ - ('all', 'all', 'repository.write'), - ('dirs', 'dirs', 'repository.admin'), - ('files', 'files', 'repository.read'), - ]) - def test_api_get_repo_nodes_by_regular_user( - self, name, ret_type, grant_perm, backend): - RepoModel().grant_user_permission(repo=backend.repo_name, - user=self.TEST_USER_LOGIN, - perm=grant_perm) + @pytest.mark.parametrize( + "name, ret_type, grant_perm", + [ + ("all", "all", "repository.write"), + ("dirs", "dirs", "repository.admin"), + ("files", "files", "repository.read"), + ], + ) + def test_api_get_repo_nodes_by_regular_user(self, name, ret_type, grant_perm, backend): + RepoModel().grant_user_permission(repo=backend.repo_name, user=self.TEST_USER_LOGIN, perm=grant_perm) Session().commit() - commit_id = 'tip' - path = '/' + commit_id = "tip" + path = "/" id_, params = build_data( - self.apikey_regular, 'get_repo_nodes', - repoid=backend.repo_name, revision=commit_id, + self.apikey_regular, + "get_repo_nodes", + repoid=backend.repo_name, + revision=commit_id, root_path=path, - ret_type=ret_type) + ret_type=ret_type, + ) response = api_call(self.app, params) # we don't the actual return types here since it's tested somewhere # else - expected = response.json['result'] + expected = response.json["result"] try: assert_ok(id_, expected, given=response.body) finally: - RepoModel().revoke_user_permission( - backend.repo_name, self.TEST_USER_LOGIN) + RepoModel().revoke_user_permission(backend.repo_name, self.TEST_USER_LOGIN) diff --git a/rhodecode/api/tests/test_get_repo_refs.py b/rhodecode/api/tests/test_get_repo_refs.py index 21b17a32..f597dc2c 100644 --- a/rhodecode/api/tests/test_get_repo_refs.py +++ b/rhodecode/api/tests/test_get_repo_refs.py @@ -23,16 +23,20 @@ from rhodecode.model.meta import Session from rhodecode.model.repo import RepoModel from rhodecode.model.user import UserModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, expected_permissions) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, expected_permissions @pytest.mark.usefixtures("testuser_api", "app") class TestGetRepo(object): def test_api_get_repo_refs(self, backend, user_util): repo = backend.create_repo() - id_, params = build_data(self.apikey, 'get_repo_refs', - **{'repoid': repo.repo_name,}) + id_, params = build_data( + self.apikey, + "get_repo_refs", + **{ + "repoid": repo.repo_name, + }, + ) response = api_call(self.app, params) expected = repo.scm_instance().refs() assert_ok(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_repos.py b/rhodecode/api/tests/test_get_repos.py index 1ee670da..dff63d8e 100644 --- a/rhodecode/api/tests/test_get_repos.py +++ b/rhodecode/api/tests/test_get_repos.py @@ -20,15 +20,14 @@ import pytest from rhodecode.model.repo import RepoModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, jsonify) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, jsonify from rhodecode.model.db import User @pytest.mark.usefixtures("testuser_api", "app") class TestGetRepos(object): def test_api_get_repos(self): - id_, params = build_data(self.apikey, 'get_repos') + id_, params = build_data(self.apikey, "get_repos") response = api_call(self.app, params) result = [] @@ -43,7 +42,7 @@ class TestGetRepos(object): repo_group = user_util.create_repo_group(auto_cleanup=True) user_util.create_repo(parent=repo_group) - id_, params = build_data(self.apikey, 'get_repos', traverse=0) + id_, params = build_data(self.apikey, "get_repos", traverse=0) response = api_call(self.app, params) result = [] @@ -54,10 +53,10 @@ class TestGetRepos(object): assert_ok(id_, expected, given=response.body) def test_api_get_repos_with_wrong_root(self): - id_, params = build_data(self.apikey, 'get_repos', root='abracadabra') + id_, params = build_data(self.apikey, "get_repos", root="abracadabra") response = api_call(self.app, params) - expected = 'Root repository group `abracadabra` does not exist' + expected = "Root repository group `abracadabra` does not exist" assert_error(id_, expected, given=response.body) def test_api_get_repos_with_root(self, user_util): @@ -68,12 +67,11 @@ class TestGetRepos(object): user_util.create_repo(parent=repo_group) # nested, should not show up - user_util._test_name = '{}/'.format(repo_group_name) + user_util._test_name = "{}/".format(repo_group_name) sub_repo_group = user_util.create_repo_group(auto_cleanup=True) user_util.create_repo(parent=sub_repo_group) - id_, params = build_data(self.apikey, 'get_repos', - root=repo_group_name, traverse=0) + id_, params = build_data(self.apikey, "get_repos", root=repo_group_name, traverse=0) response = api_call(self.app, params) result = [] @@ -92,17 +90,15 @@ class TestGetRepos(object): user_util.create_repo(parent=repo_group) # nested, should not show up - user_util._test_name = '{}/'.format(repo_group_name) + user_util._test_name = "{}/".format(repo_group_name) sub_repo_group = user_util.create_repo_group(auto_cleanup=True) user_util.create_repo(parent=sub_repo_group) - id_, params = build_data(self.apikey, 'get_repos', - root=repo_group_name, traverse=1) + id_, params = build_data(self.apikey, "get_repos", root=repo_group_name, traverse=1) response = api_call(self.app, params) result = [] - for repo in RepoModel().get_repos_for_root( - repo_group_name, traverse=True): + for repo in RepoModel().get_repos_for_root(repo_group_name, traverse=True): result.append(repo.get_api_data(include_secrets=True)) assert len(result) == 3 @@ -110,16 +106,16 @@ class TestGetRepos(object): assert_ok(id_, expected, given=response.body) def test_api_get_repos_non_admin(self): - id_, params = build_data(self.apikey_regular, 'get_repos') + id_, params = build_data(self.apikey_regular, "get_repos") response = api_call(self.app, params) user = User.get_by_username(self.TEST_USER_LOGIN) - allowed_repos = user.AuthUser().permissions['repositories'] + allowed_repos = user.AuthUser().permissions["repositories"] result = [] for repo in RepoModel().get_all(): perm = allowed_repos[repo.repo_name] - if perm in ['repository.read', 'repository.write', 'repository.admin']: + if perm in ["repository.read", "repository.write", "repository.admin"]: result.append(repo.get_api_data()) ret = jsonify(result) diff --git a/rhodecode/api/tests/test_get_server_info.py b/rhodecode/api/tests/test_get_server_info.py index 9201b57c..d78b2092 100644 --- a/rhodecode/api/tests/test_get_server_info.py +++ b/rhodecode/api/tests/test_get_server_info.py @@ -29,54 +29,54 @@ def http_host_stub(): To ensure that we can get an IP address, this test shall run with a hostname set to "localhost". """ - return 'localhost:80' + return "localhost:80" @pytest.mark.usefixtures("testuser_api", "app") class TestGetServerInfo(object): def test_api_get_server_info(self): - id_, params = build_data(self.apikey, 'get_server_info') + id_, params = build_data(self.apikey, "get_server_info") response = api_call(self.app, params) resp = response.json expected = ScmModel().get_server_info() - expected['memory'] = resp['result']['memory'] - expected['uptime'] = resp['result']['uptime'] - expected['load'] = resp['result']['load'] - expected['cpu'] = resp['result']['cpu'] - expected['storage'] = resp['result']['storage'] - expected['storage_temp'] = resp['result']['storage_temp'] - expected['storage_inodes'] = resp['result']['storage_inodes'] - expected['server'] = resp['result']['server'] + expected["memory"] = resp["result"]["memory"] + expected["uptime"] = resp["result"]["uptime"] + expected["load"] = resp["result"]["load"] + expected["cpu"] = resp["result"]["cpu"] + expected["storage"] = resp["result"]["storage"] + expected["storage_temp"] = resp["result"]["storage_temp"] + expected["storage_inodes"] = resp["result"]["storage_inodes"] + expected["server"] = resp["result"]["server"] - expected['index_storage'] = resp['result']['index_storage'] - expected['storage'] = resp['result']['storage'] + expected["index_storage"] = resp["result"]["index_storage"] + expected["storage"] = resp["result"]["storage"] assert_ok(id_, expected, given=response.body) def test_api_get_server_info_ip(self): - id_, params = build_data(self.apikey, 'get_server_info') + id_, params = build_data(self.apikey, "get_server_info") response = api_call(self.app, params) resp = response.json - expected = ScmModel().get_server_info({'SERVER_NAME': 'unknown'}) - expected['memory'] = resp['result']['memory'] - expected['uptime'] = resp['result']['uptime'] - expected['load'] = resp['result']['load'] - expected['cpu'] = resp['result']['cpu'] - expected['storage'] = resp['result']['storage'] - expected['storage_temp'] = resp['result']['storage_temp'] - expected['storage_inodes'] = resp['result']['storage_inodes'] - expected['server'] = resp['result']['server'] + expected = ScmModel().get_server_info({"SERVER_NAME": "unknown"}) + expected["memory"] = resp["result"]["memory"] + expected["uptime"] = resp["result"]["uptime"] + expected["load"] = resp["result"]["load"] + expected["cpu"] = resp["result"]["cpu"] + expected["storage"] = resp["result"]["storage"] + expected["storage_temp"] = resp["result"]["storage_temp"] + expected["storage_inodes"] = resp["result"]["storage_inodes"] + expected["server"] = resp["result"]["server"] - expected['index_storage'] = resp['result']['index_storage'] - expected['storage'] = resp['result']['storage'] + expected["index_storage"] = resp["result"]["index_storage"] + expected["storage"] = resp["result"]["storage"] assert_ok(id_, expected, given=response.body) def test_api_get_server_info_data_for_search_index_build(self): - id_, params = build_data(self.apikey, 'get_server_info') + id_, params = build_data(self.apikey, "get_server_info") response = api_call(self.app, params) resp = response.json # required by indexer - assert resp['result']['index_storage'] - assert resp['result']['storage'] + assert resp["result"]["index_storage"] + assert resp["result"]["storage"] diff --git a/rhodecode/api/tests/test_get_user.py b/rhodecode/api/tests/test_get_user.py index db4c0319..ef8c9c9c 100644 --- a/rhodecode/api/tests/test_get_user.py +++ b/rhodecode/api/tests/test_get_user.py @@ -21,64 +21,60 @@ import pytest from rhodecode.lib.auth import AuthUser from rhodecode.model.user import UserModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error @pytest.mark.usefixtures("testuser_api", "app") class TestGetUser(object): def test_api_get_user(self): - id_, params = build_data( - self.apikey, 'get_user', userid=TEST_USER_ADMIN_LOGIN) + id_, params = build_data(self.apikey, "get_user", userid=TEST_USER_ADMIN_LOGIN) response = api_call(self.app, params) usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) ret = usr.get_api_data(include_secrets=True) permissions = AuthUser(usr.user_id).permissions - ret['permissions'] = permissions - ret['permissions_summary'] = permissions + ret["permissions"] = permissions + ret["permissions_summary"] = permissions expected = ret assert_ok(id_, expected, given=response.body) def test_api_get_user_not_existing(self): - id_, params = build_data(self.apikey, 'get_user', userid='trololo') + id_, params = build_data(self.apikey, "get_user", userid="trololo") response = api_call(self.app, params) - expected = "user `%s` does not exist" % 'trololo' + expected = "user `%s` does not exist" % "trololo" assert_error(id_, expected, given=response.body) def test_api_get_user_without_giving_userid(self): - id_, params = build_data(self.apikey, 'get_user') + id_, params = build_data(self.apikey, "get_user") response = api_call(self.app, params) usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) ret = usr.get_api_data(include_secrets=True) permissions = AuthUser(usr.user_id).permissions - ret['permissions'] = permissions - ret['permissions_summary'] = permissions + ret["permissions"] = permissions + ret["permissions_summary"] = permissions expected = ret assert_ok(id_, expected, given=response.body) def test_api_get_user_without_giving_userid_non_admin(self): - id_, params = build_data(self.apikey_regular, 'get_user') + id_, params = build_data(self.apikey_regular, "get_user") response = api_call(self.app, params) usr = UserModel().get_by_username(self.TEST_USER_LOGIN) ret = usr.get_api_data(include_secrets=True) permissions = AuthUser(usr.user_id).permissions - ret['permissions'] = permissions - ret['permissions_summary'] = permissions + ret["permissions"] = permissions + ret["permissions_summary"] = permissions expected = ret assert_ok(id_, expected, given=response.body) def test_api_get_user_with_giving_userid_non_admin(self): - id_, params = build_data( - self.apikey_regular, 'get_user', - userid=self.TEST_USER_LOGIN) + id_, params = build_data(self.apikey_regular, "get_user", userid=self.TEST_USER_LOGIN) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_user_group.py b/rhodecode/api/tests/test_get_user_group.py index 72df94db..ec9385ef 100644 --- a/rhodecode/api/tests/test_get_user_group.py +++ b/rhodecode/api/tests/test_get_user_group.py @@ -19,56 +19,49 @@ import pytest from rhodecode.model.user import UserModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, expected_permissions) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, expected_permissions @pytest.mark.usefixtures("testuser_api", "app") class TestGetUserGroups(object): def test_api_get_user_group(self, user_util): user, group = user_util.create_user_with_group() - id_, params = build_data( - self.apikey, 'get_user_group', usergroupid=group.users_group_name) + id_, params = build_data(self.apikey, "get_user_group", usergroupid=group.users_group_name) response = api_call(self.app, params) ret = group.get_api_data() - ret['users'] = [user.get_api_data()] + ret["users"] = [user.get_api_data()] permissions = expected_permissions(group) - ret['permissions'] = permissions - ret['permissions_summary'] = response.json['result']['permissions_summary'] + ret["permissions"] = permissions + ret["permissions_summary"] = response.json["result"]["permissions_summary"] expected = ret assert_ok(id_, expected, given=response.body) def test_api_get_user_group_regular_user(self, user_util): user, group = user_util.create_user_with_group() - id_, params = build_data( - self.apikey_regular, 'get_user_group', - usergroupid=group.users_group_name) + id_, params = build_data(self.apikey_regular, "get_user_group", usergroupid=group.users_group_name) response = api_call(self.app, params) ret = group.get_api_data() - ret['users'] = [user.get_api_data()] + ret["users"] = [user.get_api_data()] permissions = expected_permissions(group) - ret['permissions'] = permissions - ret['permissions_summary'] = response.json['result']['permissions_summary'] + ret["permissions"] = permissions + ret["permissions_summary"] = response.json["result"]["permissions_summary"] expected = ret assert_ok(id_, expected, given=response.body) - def test_api_get_user_group_regular_user_permission_denied( - self, user_util): + def test_api_get_user_group_regular_user_permission_denied(self, user_util): group = user_util.create_user_group() user = UserModel().get_by_username(self.TEST_USER_LOGIN) group_name = group.users_group_name - user_util.grant_user_permission_to_user_group( - group, user, 'usergroup.none') + user_util.grant_user_permission_to_user_group(group, user, "usergroup.none") - id_, params = build_data( - self.apikey_regular, 'get_user_group', usergroupid=group_name) + id_, params = build_data(self.apikey_regular, "get_user_group", usergroupid=group_name) response = api_call(self.app, params) - expected = 'user group `%s` does not exist' % (group_name,) + expected = "user group `%s` does not exist" % (group_name,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_get_user_groups.py b/rhodecode/api/tests/test_get_user_groups.py index 8f333fc8..abd9baca 100644 --- a/rhodecode/api/tests/test_get_user_groups.py +++ b/rhodecode/api/tests/test_get_user_groups.py @@ -26,19 +26,23 @@ from rhodecode.lib.ext_json import json @pytest.mark.usefixtures("testuser_api", "app") class TestGetUserGroups(object): - @pytest.mark.parametrize("apikey_attr, expect_secrets", [ - ('apikey', True), - ('apikey_regular', False), - ]) + @pytest.mark.parametrize( + "apikey_attr, expect_secrets", + [ + ("apikey", True), + ("apikey_regular", False), + ], + ) def test_api_get_user_groups(self, apikey_attr, expect_secrets, user_util): first_group = user_util.create_user_group() second_group = user_util.create_user_group() - expected = [ - g.get_api_data(include_secrets=expect_secrets) - for g in (first_group, second_group)] + expected = [g.get_api_data(include_secrets=expect_secrets) for g in (first_group, second_group)] apikey = getattr(self, apikey_attr) - id_, params = build_data(apikey, 'get_user_groups', ) + id_, params = build_data( + apikey, + "get_user_groups", + ) response = api_call(self.app, params) self._assert_ok(id_, expected, response) @@ -47,22 +51,27 @@ class TestGetUserGroups(object): second_group = user_util.create_user_group() expected = [g.get_api_data() for g in (first_group, second_group)] - id_, params = build_data(self.apikey_regular, 'get_user_groups', ) + id_, params = build_data( + self.apikey_regular, + "get_user_groups", + ) response = api_call(self.app, params) self._assert_ok(id_, expected, response) def test_api_get_user_groups_regular_user_no_permission(self, user_util): group = user_util.create_user_group() user = UserModel().get_by_username(self.TEST_USER_LOGIN) - user_util.grant_user_permission_to_user_group( - group, user, 'usergroup.none') - id_, params = build_data(self.apikey_regular, 'get_user_groups', ) + user_util.grant_user_permission_to_user_group(group, user, "usergroup.none") + id_, params = build_data( + self.apikey_regular, + "get_user_groups", + ) response = api_call(self.app, params) expected = [] self._assert_ok(id_, expected, response) def _assert_ok(self, id_, expected_list, response): result = json.loads(response.body) - assert result['id'] == id_ - assert result['error'] is None - assert result['result'] == expected_list + assert result["id"] == id_ + assert result["error"] is None + assert result["result"] == expected_list diff --git a/rhodecode/api/tests/test_get_users.py b/rhodecode/api/tests/test_get_users.py index 29965e62..261fb4be 100644 --- a/rhodecode/api/tests/test_get_users.py +++ b/rhodecode/api/tests/test_get_users.py @@ -19,18 +19,19 @@ import pytest from rhodecode.model.db import User -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, jsonify) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, jsonify @pytest.mark.usefixtures("testuser_api", "app") class TestGetUsers(object): def test_api_get_users(self): - id_, params = build_data(self.apikey, 'get_users', ) + id_, params = build_data( + self.apikey, + "get_users", + ) response = api_call(self.app, params) ret_all = [] - _users = User.query().filter(User.username != User.DEFAULT_USER) \ - .order_by(User.username).all() + _users = User.query().filter(User.username != User.DEFAULT_USER).order_by(User.username).all() for usr in _users: ret = usr.get_api_data(include_secrets=True) ret_all.append(jsonify(ret)) diff --git a/rhodecode/api/tests/test_grant_user_group_permission.py b/rhodecode/api/tests/test_grant_user_group_permission.py index 5bfb8a7a..f2970c3e 100644 --- a/rhodecode/api/tests/test_grant_user_group_permission.py +++ b/rhodecode/api/tests/test_grant_user_group_permission.py @@ -20,69 +20,69 @@ import mock import pytest from rhodecode.model.repo import RepoModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestGrantUserGroupPermission(object): - @pytest.mark.parametrize("name, perm", [ - ('none', 'repository.none'), - ('read', 'repository.read'), - ('write', 'repository.write'), - ('admin', 'repository.admin') - ]) - def test_api_grant_user_group_permission( - self, name, perm, backend, user_util): + @pytest.mark.parametrize( + "name, perm", + [ + ("none", "repository.none"), + ("read", "repository.read"), + ("write", "repository.write"), + ("admin", "repository.admin"), + ], + ) + def test_api_grant_user_group_permission(self, name, perm, backend, user_util): user_group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'grant_user_group_permission', + "grant_user_group_permission", repoid=backend.repo_name, usergroupid=user_group.users_group_name, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) ret = { - 'msg': 'Granted perm: `%s` for user group: `%s` in repo: `%s`' % ( - perm, user_group.users_group_name, backend.repo_name - ), - 'success': True + "msg": "Granted perm: `%s` for user group: `%s` in repo: `%s`" + % (perm, user_group.users_group_name, backend.repo_name), + "success": True, } expected = ret assert_ok(id_, expected, given=response.body) - def test_api_grant_user_group_permission_wrong_permission( - self, backend, user_util): - perm = 'haha.no.permission' + def test_api_grant_user_group_permission_wrong_permission(self, backend, user_util): + perm = "haha.no.permission" user_group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'grant_user_group_permission', + "grant_user_group_permission", repoid=backend.repo_name, usergroupid=user_group.users_group_name, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) - expected = 'permission `%s` does not exist.' % (perm,) + expected = "permission `%s` does not exist." % (perm,) assert_error(id_, expected, given=response.body) - @mock.patch.object(RepoModel, 'grant_user_group_permission', crash) - def test_api_grant_user_group_permission_exception_when_adding( - self, backend, user_util): - perm = 'repository.read' + @mock.patch.object(RepoModel, "grant_user_group_permission", crash) + def test_api_grant_user_group_permission_exception_when_adding(self, backend, user_util): + perm = "repository.read" user_group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'grant_user_group_permission', + "grant_user_group_permission", repoid=backend.repo_name, usergroupid=user_group.users_group_name, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user group: `%s` in repo: `%s`' % ( - user_group.users_group_name, backend.repo_name - ) + expected = "failed to edit permission for user group: `%s` in repo: `%s`" % ( + user_group.users_group_name, + backend.repo_name, ) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_grant_user_group_permission_to_repo_group.py b/rhodecode/api/tests/test_grant_user_group_permission_to_repo_group.py index 770eefbd..d65df474 100644 --- a/rhodecode/api/tests/test_grant_user_group_permission_to_repo_group.py +++ b/rhodecode/api/tests/test_grant_user_group_permission_to_repo_group.py @@ -21,151 +21,141 @@ import pytest from rhodecode.model.user import UserModel from rhodecode.model.repo_group import RepoGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestGrantUserGroupPermissionFromRepoGroup(object): - @pytest.mark.parametrize("name, perm, apply_to_children", [ - ('none', 'group.none', 'none'), - ('read', 'group.read', 'none'), - ('write', 'group.write', 'none'), - ('admin', 'group.admin', 'none'), - - ('none', 'group.none', 'all'), - ('read', 'group.read', 'all'), - ('write', 'group.write', 'all'), - ('admin', 'group.admin', 'all'), - - ('none', 'group.none', 'repos'), - ('read', 'group.read', 'repos'), - ('write', 'group.write', 'repos'), - ('admin', 'group.admin', 'repos'), - - ('none', 'group.none', 'groups'), - ('read', 'group.read', 'groups'), - ('write', 'group.write', 'groups'), - ('admin', 'group.admin', 'groups'), - ]) - def test_api_grant_user_group_permission_to_repo_group( - self, name, perm, apply_to_children, user_util): + @pytest.mark.parametrize( + "name, perm, apply_to_children", + [ + ("none", "group.none", "none"), + ("read", "group.read", "none"), + ("write", "group.write", "none"), + ("admin", "group.admin", "none"), + ("none", "group.none", "all"), + ("read", "group.read", "all"), + ("write", "group.write", "all"), + ("admin", "group.admin", "all"), + ("none", "group.none", "repos"), + ("read", "group.read", "repos"), + ("write", "group.write", "repos"), + ("admin", "group.admin", "repos"), + ("none", "group.none", "groups"), + ("read", "group.read", "groups"), + ("write", "group.write", "groups"), + ("admin", "group.admin", "groups"), + ], + ) + def test_api_grant_user_group_permission_to_repo_group(self, name, perm, apply_to_children, user_util): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() user_util.create_repo(parent=repo_group) id_, params = build_data( self.apikey, - 'grant_user_group_permission_to_repo_group', + "grant_user_group_permission_to_repo_group", repogroupid=repo_group.name, usergroupid=user_group.users_group_name, perm=perm, - apply_to_children=apply_to_children,) + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) ret = { - 'msg': ( - 'Granted perm: `%s` (recursive:%s) for user group: `%s`' - ' in repo group: `%s`' % ( - perm, apply_to_children, user_group.users_group_name, - repo_group.name - ) + "msg": ( + "Granted perm: `%s` (recursive:%s) for user group: `%s`" + " in repo group: `%s`" % (perm, apply_to_children, user_group.users_group_name, repo_group.name) ), - 'success': True + "success": True, } expected = ret try: assert_ok(id_, expected, given=response.body) finally: - RepoGroupModel().revoke_user_group_permission( - repo_group.group_id, user_group.users_group_id) + RepoGroupModel().revoke_user_group_permission(repo_group.group_id, user_group.users_group_id) @pytest.mark.parametrize( - "name, perm, apply_to_children, grant_admin, access_ok", [ - ('none_fails', 'group.none', 'none', False, False), - ('read_fails', 'group.read', 'none', False, False), - ('write_fails', 'group.write', 'none', False, False), - ('admin_fails', 'group.admin', 'none', False, False), - + "name, perm, apply_to_children, grant_admin, access_ok", + [ + ("none_fails", "group.none", "none", False, False), + ("read_fails", "group.read", "none", False, False), + ("write_fails", "group.write", "none", False, False), + ("admin_fails", "group.admin", "none", False, False), # with granted perms - ('none_ok', 'group.none', 'none', True, True), - ('read_ok', 'group.read', 'none', True, True), - ('write_ok', 'group.write', 'none', True, True), - ('admin_ok', 'group.admin', 'none', True, True), - ] + ("none_ok", "group.none", "none", True, True), + ("read_ok", "group.read", "none", True, True), + ("write_ok", "group.write", "none", True, True), + ("admin_ok", "group.admin", "none", True, True), + ], ) def test_api_grant_user_group_permission_to_repo_group_by_regular_user( - self, name, perm, apply_to_children, grant_admin, access_ok, - user_util): + self, name, perm, apply_to_children, grant_admin, access_ok, user_util + ): user = UserModel().get_by_username(self.TEST_USER_LOGIN) user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() if grant_admin: - user_util.grant_user_permission_to_repo_group( - repo_group, user, 'group.admin') + user_util.grant_user_permission_to_repo_group(repo_group, user, "group.admin") id_, params = build_data( self.apikey_regular, - 'grant_user_group_permission_to_repo_group', + "grant_user_group_permission_to_repo_group", repogroupid=repo_group.name, usergroupid=user_group.users_group_name, perm=perm, - apply_to_children=apply_to_children,) + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) if access_ok: ret = { - 'msg': ( - 'Granted perm: `%s` (recursive:%s) for user group: `%s`' - ' in repo group: `%s`' % ( - perm, apply_to_children, user_group.users_group_name, - repo_group.name - ) + "msg": ( + "Granted perm: `%s` (recursive:%s) for user group: `%s`" + " in repo group: `%s`" % (perm, apply_to_children, user_group.users_group_name, repo_group.name) ), - 'success': True + "success": True, } expected = ret try: assert_ok(id_, expected, given=response.body) finally: - RepoGroupModel().revoke_user_group_permission( - repo_group.group_id, user_group.users_group_id) + RepoGroupModel().revoke_user_group_permission(repo_group.group_id, user_group.users_group_id) else: - expected = 'repository group `%s` does not exist' % (repo_group.name,) + expected = "repository group `%s` does not exist" % (repo_group.name,) assert_error(id_, expected, given=response.body) - def test_api_grant_user_group_permission_to_repo_group_wrong_permission( - self, user_util): + def test_api_grant_user_group_permission_to_repo_group_wrong_permission(self, user_util): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() - perm = 'haha.no.permission' + perm = "haha.no.permission" id_, params = build_data( self.apikey, - 'grant_user_group_permission_to_repo_group', + "grant_user_group_permission_to_repo_group", repogroupid=repo_group.name, usergroupid=user_group.users_group_name, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) - expected = 'permission `%s` does not exist. Permission should start with prefix: `group.`' % (perm,) + expected = "permission `%s` does not exist. Permission should start with prefix: `group.`" % (perm,) assert_error(id_, expected, given=response.body) - @mock.patch.object(RepoGroupModel, 'grant_user_group_permission', crash) - def test_api_grant_user_group_permission_exception_when_adding_2( - self, user_util): + @mock.patch.object(RepoGroupModel, "grant_user_group_permission", crash) + def test_api_grant_user_group_permission_exception_when_adding_2(self, user_util): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() - perm = 'group.read' + perm = "group.read" id_, params = build_data( self.apikey, - 'grant_user_group_permission_to_repo_group', + "grant_user_group_permission_to_repo_group", repogroupid=repo_group.name, usergroupid=user_group.users_group_name, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user group: `%s`' - ' in repo group: `%s`' % ( - user_group.users_group_name, repo_group.name) + expected = "failed to edit permission for user group: `%s` in repo group: `%s`" % ( + user_group.users_group_name, + repo_group.name, ) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_grant_user_group_permission_to_user_group.py b/rhodecode/api/tests/test_grant_user_group_permission_to_user_group.py index 0c64acd6..4beea1c8 100644 --- a/rhodecode/api/tests/test_grant_user_group_permission_to_user_group.py +++ b/rhodecode/api/tests/test_grant_user_group_permission_to_user_group.py @@ -19,77 +19,71 @@ import pytest from rhodecode.model.user_group import UserGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error @pytest.mark.usefixtures("testuser_api", "app") class TestGrantUserGroupPermissionFromUserGroup(object): - @pytest.mark.parametrize("name, perm", [ - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - ]) - def test_api_grant_user_group_permission_to_user_group( - self, name, perm, user_util): + @pytest.mark.parametrize( + "name, perm", + [ + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ], + ) + def test_api_grant_user_group_permission_to_user_group(self, name, perm, user_util): group = user_util.create_user_group() target_group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'grant_user_group_permission_to_user_group', + "grant_user_group_permission_to_user_group", usergroupid=target_group.users_group_name, sourceusergroupid=group.users_group_name, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) expected = { - 'msg': ( - 'Granted perm: `%s` for user group: `%s`' - ' in user group: `%s`' % ( - perm, group.users_group_name, - target_group.users_group_name - ) + "msg": ( + "Granted perm: `%s` for user group: `%s`" + " in user group: `%s`" % (perm, group.users_group_name, target_group.users_group_name) ), - 'success': True + "success": True, } try: assert_ok(id_, expected, given=response.body) finally: - UserGroupModel().revoke_user_group_permission( - target_group.users_group_id, group.users_group_id) + UserGroupModel().revoke_user_group_permission(target_group.users_group_id, group.users_group_id) - def test_api_grant_user_group_permission_to_user_group_same_failure( - self, user_util): + def test_api_grant_user_group_permission_to_user_group_same_failure(self, user_util): group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'grant_user_group_permission_to_user_group', + "grant_user_group_permission_to_user_group", usergroupid=group.users_group_name, sourceusergroupid=group.users_group_name, - perm='usergroup.none') + perm="usergroup.none", + ) response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user group: `%s`' - ' in user group: `%s`' % ( - group.users_group_name, group.users_group_name) + expected = "failed to edit permission for user group: `%s` in user group: `%s`" % ( + group.users_group_name, + group.users_group_name, ) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_grant_user_permission.py b/rhodecode/api/tests/test_grant_user_permission.py index d3bae99d..ff96970a 100644 --- a/rhodecode/api/tests/test_grant_user_permission.py +++ b/rhodecode/api/tests/test_grant_user_permission.py @@ -20,66 +20,53 @@ import mock import pytest from rhodecode.model.repo import RepoModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestGrantUserPermission(object): - @pytest.mark.parametrize("name, perm", [ - ('none', 'repository.none'), - ('read', 'repository.read'), - ('write', 'repository.write'), - ('admin', 'repository.admin') - ]) + @pytest.mark.parametrize( + "name, perm", + [ + ("none", "repository.none"), + ("read", "repository.read"), + ("write", "repository.write"), + ("admin", "repository.admin"), + ], + ) def test_api_grant_user_permission(self, name, perm, backend, user_util): user = user_util.create_user() id_, params = build_data( - self.apikey, - 'grant_user_permission', - repoid=backend.repo_name, - userid=user.username, - perm=perm) + self.apikey, "grant_user_permission", repoid=backend.repo_name, userid=user.username, perm=perm + ) response = api_call(self.app, params) ret = { - 'msg': 'Granted perm: `%s` for user: `%s` in repo: `%s`' % ( - perm, user.username, backend.repo_name - ), - 'success': True + "msg": "Granted perm: `%s` for user: `%s` in repo: `%s`" % (perm, user.username, backend.repo_name), + "success": True, } expected = ret assert_ok(id_, expected, given=response.body) - def test_api_grant_user_permission_wrong_permission( - self, backend, user_util): + def test_api_grant_user_permission_wrong_permission(self, backend, user_util): user = user_util.create_user() - perm = 'haha.no.permission' + perm = "haha.no.permission" id_, params = build_data( - self.apikey, - 'grant_user_permission', - repoid=backend.repo_name, - userid=user.username, - perm=perm) - response = api_call(self.app, params) - - expected = 'permission `%s` does not exist.' % (perm,) - assert_error(id_, expected, given=response.body) - - @mock.patch.object(RepoModel, 'grant_user_permission', crash) - def test_api_grant_user_permission_exception_when_adding( - self, backend, user_util): - user = user_util.create_user() - perm = 'repository.read' - id_, params = build_data( - self.apikey, - 'grant_user_permission', - repoid=backend.repo_name, - userid=user.username, - perm=perm) - response = api_call(self.app, params) - - expected = 'failed to edit permission for user: `%s` in repo: `%s`' % ( - user.username, backend.repo_name + self.apikey, "grant_user_permission", repoid=backend.repo_name, userid=user.username, perm=perm ) + response = api_call(self.app, params) + + expected = "permission `%s` does not exist." % (perm,) + assert_error(id_, expected, given=response.body) + + @mock.patch.object(RepoModel, "grant_user_permission", crash) + def test_api_grant_user_permission_exception_when_adding(self, backend, user_util): + user = user_util.create_user() + perm = "repository.read" + id_, params = build_data( + self.apikey, "grant_user_permission", repoid=backend.repo_name, userid=user.username, perm=perm + ) + response = api_call(self.app, params) + + expected = "failed to edit permission for user: `%s` in repo: `%s`" % (user.username, backend.repo_name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_grant_user_permission_to_repo_group.py b/rhodecode/api/tests/test_grant_user_permission_to_repo_group.py index a0053326..7e1f1f76 100644 --- a/rhodecode/api/tests/test_grant_user_permission_to_repo_group.py +++ b/rhodecode/api/tests/test_grant_user_permission_to_repo_group.py @@ -21,135 +21,131 @@ import pytest from rhodecode.model.user import UserModel from rhodecode.model.repo_group import RepoGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestGrantUserPermissionFromRepoGroup(object): - @pytest.mark.parametrize("name, perm, apply_to_children", [ - ('none', 'group.none', 'none'), - ('read', 'group.read', 'none'), - ('write', 'group.write', 'none'), - ('admin', 'group.admin', 'none'), - - ('none', 'group.none', 'all'), - ('read', 'group.read', 'all'), - ('write', 'group.write', 'all'), - ('admin', 'group.admin', 'all'), - - ('none', 'group.none', 'repos'), - ('read', 'group.read', 'repos'), - ('write', 'group.write', 'repos'), - ('admin', 'group.admin', 'repos'), - - ('none', 'group.none', 'groups'), - ('read', 'group.read', 'groups'), - ('write', 'group.write', 'groups'), - ('admin', 'group.admin', 'groups'), - ]) - def test_api_grant_user_permission_to_repo_group( - self, name, perm, apply_to_children, user_util): + @pytest.mark.parametrize( + "name, perm, apply_to_children", + [ + ("none", "group.none", "none"), + ("read", "group.read", "none"), + ("write", "group.write", "none"), + ("admin", "group.admin", "none"), + ("none", "group.none", "all"), + ("read", "group.read", "all"), + ("write", "group.write", "all"), + ("admin", "group.admin", "all"), + ("none", "group.none", "repos"), + ("read", "group.read", "repos"), + ("write", "group.write", "repos"), + ("admin", "group.admin", "repos"), + ("none", "group.none", "groups"), + ("read", "group.read", "groups"), + ("write", "group.write", "groups"), + ("admin", "group.admin", "groups"), + ], + ) + def test_api_grant_user_permission_to_repo_group(self, name, perm, apply_to_children, user_util): user = user_util.create_user() repo_group = user_util.create_repo_group() id_, params = build_data( - self.apikey, 'grant_user_permission_to_repo_group', - repogroupid=repo_group.name, userid=user.username, - perm=perm, apply_to_children=apply_to_children) + self.apikey, + "grant_user_permission_to_repo_group", + repogroupid=repo_group.name, + userid=user.username, + perm=perm, + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) ret = { - 'msg': ( - 'Granted perm: `%s` (recursive:%s) for user: `%s`' - ' in repo group: `%s`' % ( - perm, apply_to_children, user.username, repo_group.name - ) + "msg": ( + "Granted perm: `%s` (recursive:%s) for user: `%s`" + " in repo group: `%s`" % (perm, apply_to_children, user.username, repo_group.name) ), - 'success': True + "success": True, } expected = ret assert_ok(id_, expected, given=response.body) @pytest.mark.parametrize( - "name, perm, apply_to_children, grant_admin, access_ok", [ - ('none_fails', 'group.none', 'none', False, False), - ('read_fails', 'group.read', 'none', False, False), - ('write_fails', 'group.write', 'none', False, False), - ('admin_fails', 'group.admin', 'none', False, False), - + "name, perm, apply_to_children, grant_admin, access_ok", + [ + ("none_fails", "group.none", "none", False, False), + ("read_fails", "group.read", "none", False, False), + ("write_fails", "group.write", "none", False, False), + ("admin_fails", "group.admin", "none", False, False), # with granted perms - ('none_ok', 'group.none', 'none', True, True), - ('read_ok', 'group.read', 'none', True, True), - ('write_ok', 'group.write', 'none', True, True), - ('admin_ok', 'group.admin', 'none', True, True), - ] + ("none_ok", "group.none", "none", True, True), + ("read_ok", "group.read", "none", True, True), + ("write_ok", "group.write", "none", True, True), + ("admin_ok", "group.admin", "none", True, True), + ], ) def test_api_grant_user_permission_to_repo_group_by_regular_user( - self, name, perm, apply_to_children, grant_admin, access_ok, - user_util): + self, name, perm, apply_to_children, grant_admin, access_ok, user_util + ): user = user_util.create_user() repo_group = user_util.create_repo_group() if grant_admin: test_user = UserModel().get_by_username(self.TEST_USER_LOGIN) - user_util.grant_user_permission_to_repo_group( - repo_group, test_user, 'group.admin') + user_util.grant_user_permission_to_repo_group(repo_group, test_user, "group.admin") id_, params = build_data( - self.apikey_regular, 'grant_user_permission_to_repo_group', - repogroupid=repo_group.name, userid=user.username, - perm=perm, apply_to_children=apply_to_children) + self.apikey_regular, + "grant_user_permission_to_repo_group", + repogroupid=repo_group.name, + userid=user.username, + perm=perm, + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) if access_ok: ret = { - 'msg': ( - 'Granted perm: `%s` (recursive:%s) for user: `%s`' - ' in repo group: `%s`' % ( - perm, apply_to_children, user.username, repo_group.name - ) + "msg": ( + "Granted perm: `%s` (recursive:%s) for user: `%s`" + " in repo group: `%s`" % (perm, apply_to_children, user.username, repo_group.name) ), - 'success': True + "success": True, } expected = ret assert_ok(id_, expected, given=response.body) else: - expected = 'repository group `%s` does not exist' % ( - repo_group.name, ) + expected = "repository group `%s` does not exist" % (repo_group.name,) assert_error(id_, expected, given=response.body) - def test_api_grant_user_permission_to_repo_group_wrong_permission( - self, user_util): + def test_api_grant_user_permission_to_repo_group_wrong_permission(self, user_util): user = user_util.create_user() repo_group = user_util.create_repo_group() - perm = 'haha.no.permission' + perm = "haha.no.permission" id_, params = build_data( self.apikey, - 'grant_user_permission_to_repo_group', + "grant_user_permission_to_repo_group", repogroupid=repo_group.name, userid=user.username, - perm=perm) - response = api_call(self.app, params) - - expected = 'permission `%s` does not exist. Permission should start with prefix: `group.`' % (perm,) - assert_error(id_, expected, given=response.body) - - @mock.patch.object(RepoGroupModel, 'grant_user_permission', crash) - def test_api_grant_user_permission_to_repo_group_exception_when_adding( - self, user_util): - user = user_util.create_user() - repo_group = user_util.create_repo_group() - perm = 'group.read' - id_, params = build_data( - self.apikey, - 'grant_user_permission_to_repo_group', - repogroupid=repo_group.name, - userid=user.username, - perm=perm) - response = api_call(self.app, params) - - expected = ( - 'failed to edit permission for user: `%s` in repo group: `%s`' % ( - user.username, repo_group.name - ) + perm=perm, ) + response = api_call(self.app, params) + + expected = "permission `%s` does not exist. Permission should start with prefix: `group.`" % (perm,) + assert_error(id_, expected, given=response.body) + + @mock.patch.object(RepoGroupModel, "grant_user_permission", crash) + def test_api_grant_user_permission_to_repo_group_exception_when_adding(self, user_util): + user = user_util.create_user() + repo_group = user_util.create_repo_group() + perm = "group.read" + id_, params = build_data( + self.apikey, + "grant_user_permission_to_repo_group", + repogroupid=repo_group.name, + userid=user.username, + perm=perm, + ) + response = api_call(self.app, params) + + expected = "failed to edit permission for user: `%s` in repo group: `%s`" % (user.username, repo_group.name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_grant_user_permission_to_user_group.py b/rhodecode/api/tests/test_grant_user_permission_to_user_group.py index 757649f9..f95a4ce5 100644 --- a/rhodecode/api/tests/test_grant_user_permission_to_user_group.py +++ b/rhodecode/api/tests/test_grant_user_permission_to_user_group.py @@ -21,134 +21,132 @@ import pytest from rhodecode.model.user import UserModel from rhodecode.model.user_group import UserGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestGrantUserPermissionFromUserGroup(object): - @pytest.mark.parametrize("name, perm", [ - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - - ('none', 'usergroup.none'), - ('read', 'usergroup.read'), - ('write', 'usergroup.write'), - ('admin', 'usergroup.admin'), - ]) - def test_api_grant_user_permission_to_user_group( - self, name, perm, user_util): + @pytest.mark.parametrize( + "name, perm", + [ + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ("none", "usergroup.none"), + ("read", "usergroup.read"), + ("write", "usergroup.write"), + ("admin", "usergroup.admin"), + ], + ) + def test_api_grant_user_permission_to_user_group(self, name, perm, user_util): user = user_util.create_user() group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'grant_user_permission_to_user_group', + "grant_user_permission_to_user_group", usergroupid=group.users_group_name, userid=user.username, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) ret = { - 'msg': 'Granted perm: `%s` for user: `%s` in user group: `%s`' % ( - perm, user.username, group.users_group_name - ), - 'success': True + "msg": "Granted perm: `%s` for user: `%s` in user group: `%s`" + % (perm, user.username, group.users_group_name), + "success": True, } expected = ret assert_ok(id_, expected, given=response.body) - @pytest.mark.parametrize("name, perm, grant_admin, access_ok", [ - ('none_fails', 'usergroup.none', False, False), - ('read_fails', 'usergroup.read', False, False), - ('write_fails', 'usergroup.write', False, False), - ('admin_fails', 'usergroup.admin', False, False), - - # with granted perms - ('none_ok', 'usergroup.none', True, True), - ('read_ok', 'usergroup.read', True, True), - ('write_ok', 'usergroup.write', True, True), - ('admin_ok', 'usergroup.admin', True, True), - ]) + @pytest.mark.parametrize( + "name, perm, grant_admin, access_ok", + [ + ("none_fails", "usergroup.none", False, False), + ("read_fails", "usergroup.read", False, False), + ("write_fails", "usergroup.write", False, False), + ("admin_fails", "usergroup.admin", False, False), + # with granted perms + ("none_ok", "usergroup.none", True, True), + ("read_ok", "usergroup.read", True, True), + ("write_ok", "usergroup.write", True, True), + ("admin_ok", "usergroup.admin", True, True), + ], + ) def test_api_grant_user_permission_to_user_group_by_regular_user( - self, name, perm, grant_admin, access_ok, user_util): + self, name, perm, grant_admin, access_ok, user_util + ): api_user = UserModel().get_by_username(self.TEST_USER_LOGIN) user = user_util.create_user() group = user_util.create_user_group() # grant the user ability to at least read the group - permission = 'usergroup.admin' if grant_admin else 'usergroup.read' - user_util.grant_user_permission_to_user_group( - group, api_user, permission) + permission = "usergroup.admin" if grant_admin else "usergroup.read" + user_util.grant_user_permission_to_user_group(group, api_user, permission) id_, params = build_data( self.apikey_regular, - 'grant_user_permission_to_user_group', + "grant_user_permission_to_user_group", usergroupid=group.users_group_name, userid=user.username, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) if access_ok: ret = { - 'msg': ( - 'Granted perm: `%s` for user: `%s` in user group: `%s`' % ( - perm, user.username, group.users_group_name - ) + "msg": ( + "Granted perm: `%s` for user: `%s` in user group: `%s`" + % (perm, user.username, group.users_group_name) ), - 'success': True + "success": True, } expected = ret assert_ok(id_, expected, given=response.body) else: - expected = 'user group `%s` does not exist' % ( - group.users_group_name) + expected = "user group `%s` does not exist" % (group.users_group_name) assert_error(id_, expected, given=response.body) - def test_api_grant_user_permission_to_user_group_wrong_permission( - self, user_util): + def test_api_grant_user_permission_to_user_group_wrong_permission(self, user_util): user = user_util.create_user() group = user_util.create_user_group() - perm = 'haha.no.permission' + perm = "haha.no.permission" id_, params = build_data( self.apikey, - 'grant_user_permission_to_user_group', + "grant_user_permission_to_user_group", usergroupid=group.users_group_name, userid=user.username, - perm=perm) + perm=perm, + ) response = api_call(self.app, params) - expected = 'permission `%s` does not exist. Permission should start with prefix: `usergroup.`' % perm + expected = "permission `%s` does not exist. Permission should start with prefix: `usergroup.`" % perm assert_error(id_, expected, given=response.body) - def test_api_grant_user_permission_to_user_group_exception_when_adding( - self, user_util): + def test_api_grant_user_permission_to_user_group_exception_when_adding(self, user_util): user = user_util.create_user() group = user_util.create_user_group() - perm = 'usergroup.read' + perm = "usergroup.read" id_, params = build_data( self.apikey, - 'grant_user_permission_to_user_group', + "grant_user_permission_to_user_group", usergroupid=group.users_group_name, userid=user.username, - perm=perm) - with mock.patch.object(UserGroupModel, 'grant_user_permission', crash): + perm=perm, + ) + with mock.patch.object(UserGroupModel, "grant_user_permission", crash): response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user: `%s` in user group: `%s`' % ( - user.username, group.users_group_name - ) + expected = "failed to edit permission for user: `%s` in user group: `%s`" % ( + user.username, + group.users_group_name, ) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_invalidate_cache.py b/rhodecode/api/tests/test_invalidate_cache.py index 0d2d0d59..50dff33c 100644 --- a/rhodecode/api/tests/test_invalidate_cache.py +++ b/rhodecode/api/tests/test_invalidate_cache.py @@ -20,14 +20,12 @@ import mock import pytest from rhodecode.model.scm import ScmModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash from rhodecode.model.repo import RepoModel @pytest.mark.usefixtures("testuser_api", "app") class TestInvalidateCache(object): - def _set_cache(self, repo_name): repo = RepoModel().get_by_repo_name(repo_name) repo.scm_instance(cache=True) @@ -35,31 +33,27 @@ class TestInvalidateCache(object): def test_api_invalidate_cache(self, backend): self._set_cache(backend.repo_name) - id_, params = build_data( - self.apikey, 'invalidate_cache', repoid=backend.repo_name) + id_, params = build_data(self.apikey, "invalidate_cache", repoid=backend.repo_name) response = api_call(self.app, params) expected = { - 'msg': "Cache for repository `%s` was invalidated" % ( - backend.repo_name,), - 'repository': backend.repo_name, + "msg": "Cache for repository `%s` was invalidated" % (backend.repo_name,), + "repository": backend.repo_name, } assert_ok(id_, expected, given=response.body) - @mock.patch.object(ScmModel, 'mark_for_invalidation', crash) + @mock.patch.object(ScmModel, "mark_for_invalidation", crash) def test_api_invalidate_cache_error(self, backend): - id_, params = build_data( - self.apikey, 'invalidate_cache', repoid=backend.repo_name) + id_, params = build_data(self.apikey, "invalidate_cache", repoid=backend.repo_name) response = api_call(self.app, params) - expected = 'Error occurred during cache invalidation action' + expected = "Error occurred during cache invalidation action" assert_error(id_, expected, given=response.body) def test_api_invalidate_cache_regular_user_no_permission(self, backend): self._set_cache(backend.repo_name) - id_, params = build_data( - self.apikey_regular, 'invalidate_cache', repoid=backend.repo_name) + id_, params = build_data(self.apikey_regular, "invalidate_cache", repoid=backend.repo_name) response = api_call(self.app, params) expected = "repository `%s` does not exist" % (backend.repo_name,) diff --git a/rhodecode/api/tests/test_merge_pull_request.py b/rhodecode/api/tests/test_merge_pull_request.py index ec14d3e1..9f9e22e8 100644 --- a/rhodecode/api/tests/test_merge_pull_request.py +++ b/rhodecode/api/tests/test_merge_pull_request.py @@ -21,13 +21,11 @@ import pytest from rhodecode.model.db import UserLog, PullRequest from rhodecode.model.meta import Session from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestMergePullRequest(object): - @pytest.mark.backends("git", "hg") def test_api_merge_pull_request_merge_failed(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request(mergeable=True) @@ -35,9 +33,8 @@ class TestMergePullRequest(object): pull_request_repo = pull_request.target_repo.repo_name id_, params = build_data( - self.apikey, 'merge_pull_request', - repoid=pull_request_repo, - pullrequestid=pull_request_id) + self.apikey, "merge_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id + ) response = api_call(self.app, params) @@ -46,13 +43,11 @@ class TestMergePullRequest(object): # middleware. Therefore we need to add it back here if we want to use it. Session().add(pull_request) - expected = 'merge not possible for following reasons: ' \ - 'Pull request reviewer approval is pending.' + expected = "merge not possible for following reasons: Pull request reviewer approval is pending." assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") - def test_api_merge_pull_request_merge_failed_disallowed_state( - self, pr_util, no_notifications): + def test_api_merge_pull_request_merge_failed_disallowed_state(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request(mergeable=True, approved=True) pull_request_id = pull_request.pull_request_id pull_request_repo = pull_request.target_repo.repo_name @@ -63,14 +58,13 @@ class TestMergePullRequest(object): Session().commit() id_, params = build_data( - self.apikey, 'merge_pull_request', - repoid=pull_request_repo, - pullrequestid=pull_request_id) + self.apikey, "merge_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id + ) response = api_call(self.app, params) - expected = 'Operation forbidden because pull request is in state {}, '\ - 'only state {} is allowed.'.format(PullRequest.STATE_UPDATING, - PullRequest.STATE_CREATED) + expected = "Operation forbidden because pull request is in state {}, only state {} is allowed.".format( + PullRequest.STATE_UPDATING, PullRequest.STATE_CREATED + ) assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") @@ -82,58 +76,60 @@ class TestMergePullRequest(object): pull_request_repo = pull_request.target_repo.repo_name id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id, - status='approved') + status="approved", + ) response = api_call(self.app, params) expected = { - 'comment_id': response.json.get('result', {}).get('comment_id'), - 'pull_request_id': pull_request_id, - 'status': {'given': 'approved', 'was_changed': True} + "comment_id": response.json.get("result", {}).get("comment_id"), + "pull_request_id": pull_request_id, + "status": {"given": "approved", "was_changed": True}, } assert_ok(id_, expected, given=response.body) id_, params = build_data( - self.apikey, 'merge_pull_request', - repoid=pull_request_repo, - pullrequestid=pull_request_id) + self.apikey, "merge_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id + ) response = api_call(self.app, params) pull_request = PullRequest.get(pull_request_id) expected = { - 'executed': True, - 'failure_reason': 0, - 'merge_status_message': 'This pull request can be automatically merged.', - 'possible': True, - 'merge_commit_id': pull_request.shadow_merge_ref.commit_id, - 'merge_ref': pull_request.shadow_merge_ref.asdict() + "executed": True, + "failure_reason": 0, + "merge_status_message": "This pull request can be automatically merged.", + "possible": True, + "merge_commit_id": pull_request.shadow_merge_ref.commit_id, + "merge_ref": pull_request.shadow_merge_ref.asdict(), } assert_ok(id_, expected, response.body) - journal = UserLog.query()\ - .filter(UserLog.user_id == author)\ - .filter(UserLog.repository_id == repo) \ - .order_by(UserLog.user_log_id.asc()) \ + journal = ( + UserLog.query() + .filter(UserLog.user_id == author) + .filter(UserLog.repository_id == repo) + .order_by(UserLog.user_log_id.asc()) .all() - assert journal[-2].action == 'repo.pull_request.merge' - assert journal[-1].action == 'repo.pull_request.close' + ) + assert journal[-2].action == "repo.pull_request.merge" + assert journal[-1].action == "repo.pull_request.close" id_, params = build_data( - self.apikey, 'merge_pull_request', - repoid=pull_request_repo, pullrequestid=pull_request_id) + self.apikey, "merge_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id + ) response = api_call(self.app, params) - expected = 'merge not possible for following reasons: This pull request is closed.' + expected = "merge not possible for following reasons: This pull request is closed." assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") - def test_api_merge_pull_request_as_another_user_no_perms_to_merge( - self, pr_util, no_notifications, user_util): + def test_api_merge_pull_request_as_another_user_no_perms_to_merge(self, pr_util, no_notifications, user_util): merge_user = user_util.create_user() merge_user_id = merge_user.user_id merge_user_username = merge_user.username @@ -144,28 +140,32 @@ class TestMergePullRequest(object): pull_request_repo = pull_request.target_repo.repo_name id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id, - status='approved') - - response = api_call(self.app, params) - expected = { - 'comment_id': response.json.get('result', {}).get('comment_id'), - 'pull_request_id': pull_request_id, - 'status': {'given': 'approved', 'was_changed': True} - } - assert_ok(id_, expected, given=response.body) - id_, params = build_data( - self.apikey, 'merge_pull_request', - repoid=pull_request_repo, - pullrequestid=pull_request_id, - userid=merge_user_id + status="approved", ) response = api_call(self.app, params) - expected = 'merge not possible for following reasons: User `{}` ' \ - 'not allowed to perform merge.'.format(merge_user_username) + expected = { + "comment_id": response.json.get("result", {}).get("comment_id"), + "pull_request_id": pull_request_id, + "status": {"given": "approved", "was_changed": True}, + } + assert_ok(id_, expected, given=response.body) + id_, params = build_data( + self.apikey, + "merge_pull_request", + repoid=pull_request_repo, + pullrequestid=pull_request_id, + userid=merge_user_id, + ) + + response = api_call(self.app, params) + expected = "merge not possible for following reasons: User `{}` not allowed to perform merge.".format( + merge_user_username + ) assert_error(id_, expected, response.body) @pytest.mark.backends("git", "hg") @@ -173,32 +173,34 @@ class TestMergePullRequest(object): merge_user = user_util.create_user() merge_user_id = merge_user.user_id pull_request = pr_util.create_pull_request(mergeable=True, approved=True) - user_util.grant_user_permission_to_repo( - pull_request.target_repo, merge_user, 'repository.write') + user_util.grant_user_permission_to_repo(pull_request.target_repo, merge_user, "repository.write") author = pull_request.user_id repo = pull_request.target_repo.repo_id pull_request_id = pull_request.pull_request_id pull_request_repo = pull_request.target_repo.repo_name id_, params = build_data( - self.apikey, 'comment_pull_request', + self.apikey, + "comment_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id, - status='approved') + status="approved", + ) response = api_call(self.app, params) expected = { - 'comment_id': response.json.get('result', {}).get('comment_id'), - 'pull_request_id': pull_request_id, - 'status': {'given': 'approved', 'was_changed': True} + "comment_id": response.json.get("result", {}).get("comment_id"), + "pull_request_id": pull_request_id, + "status": {"given": "approved", "was_changed": True}, } assert_ok(id_, expected, given=response.body) id_, params = build_data( - self.apikey, 'merge_pull_request', + self.apikey, + "merge_pull_request", repoid=pull_request_repo, pullrequestid=pull_request_id, - userid=merge_user_id + userid=merge_user_id, ) response = api_call(self.app, params) @@ -206,52 +208,60 @@ class TestMergePullRequest(object): pull_request = PullRequest.get(pull_request_id) expected = { - 'executed': True, - 'failure_reason': 0, - 'merge_status_message': 'This pull request can be automatically merged.', - 'possible': True, - 'merge_commit_id': pull_request.shadow_merge_ref.commit_id, - 'merge_ref': pull_request.shadow_merge_ref.asdict() + "executed": True, + "failure_reason": 0, + "merge_status_message": "This pull request can be automatically merged.", + "possible": True, + "merge_commit_id": pull_request.shadow_merge_ref.commit_id, + "merge_ref": pull_request.shadow_merge_ref.asdict(), } assert_ok(id_, expected, response.body) - journal = UserLog.query() \ - .filter(UserLog.user_id == merge_user_id) \ - .filter(UserLog.repository_id == repo) \ - .order_by(UserLog.user_log_id.asc()) \ + journal = ( + UserLog.query() + .filter(UserLog.user_id == merge_user_id) + .filter(UserLog.repository_id == repo) + .order_by(UserLog.user_log_id.asc()) .all() - assert journal[-2].action == 'repo.pull_request.merge' - assert journal[-1].action == 'repo.pull_request.close' + ) + assert journal[-2].action == "repo.pull_request.merge" + assert journal[-1].action == "repo.pull_request.close" id_, params = build_data( - self.apikey, 'merge_pull_request', - repoid=pull_request_repo, pullrequestid=pull_request_id, userid=merge_user_id) + self.apikey, + "merge_pull_request", + repoid=pull_request_repo, + pullrequestid=pull_request_id, + userid=merge_user_id, + ) response = api_call(self.app, params) - expected = 'merge not possible for following reasons: This pull request is closed.' + expected = "merge not possible for following reasons: This pull request is closed." assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") def test_api_merge_pull_request_repo_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'merge_pull_request', - repoid=666, pullrequestid=pull_request.pull_request_id) + self.apikey, "merge_pull_request", repoid=666, pullrequestid=pull_request.pull_request_id + ) response = api_call(self.app, params) - expected = 'repository `666` does not exist' + expected = "repository `666` does not exist" assert_error(id_, expected, given=response.body) @pytest.mark.backends("git", "hg") def test_api_merge_pull_request_non_admin_with_userid_error(self, pr_util): pull_request = pr_util.create_pull_request(mergeable=True) id_, params = build_data( - self.apikey_regular, 'merge_pull_request', + self.apikey_regular, + "merge_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - userid=TEST_USER_ADMIN_LOGIN) + userid=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_pull.py b/rhodecode/api/tests/test_pull.py index 216cd6fa..83f58bf0 100644 --- a/rhodecode/api/tests/test_pull.py +++ b/rhodecode/api/tests/test_pull.py @@ -21,13 +21,11 @@ import mock import pytest from rhodecode.tests import TESTS_TMP_PATH -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error @pytest.mark.usefixtures("testuser_api", "app") class TestPull(object): - @pytest.mark.backends("git", "hg") def test_api_pull(self, backend): r = backend.create_repo() @@ -35,19 +33,20 @@ class TestPull(object): clone_uri = os.path.join(TESTS_TMP_PATH, backend.repo_name) r.clone_uri = clone_uri - id_, params = build_data(self.apikey, 'pull', repoid=repo_name,) - with mock.patch('rhodecode.model.scm.url_validator'): + id_, params = build_data( + self.apikey, + "pull", + repoid=repo_name, + ) + with mock.patch("rhodecode.model.scm.url_validator"): response = api_call(self.app, params) - msg = 'Pulled from url `%s` on repo `%s`' % ( - clone_uri, repo_name) - expected = {'msg': msg, - 'repository': repo_name} + msg = "Pulled from url `%s` on repo `%s`" % (clone_uri, repo_name) + expected = {"msg": msg, "repository": repo_name} assert_ok(id_, expected, given=response.body) def test_api_pull_error(self, backend): - id_, params = build_data( - self.apikey, 'pull', repoid=backend.repo_name) + id_, params = build_data(self.apikey, "pull", repoid=backend.repo_name) response = api_call(self.app, params) - expected = 'Unable to pull changes from `None`' + expected = "Unable to pull changes from `None`" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_remove_field_from_repo.py b/rhodecode/api/tests/test_remove_field_from_repo.py index 970330aa..5cff831d 100644 --- a/rhodecode/api/tests/test_remove_field_from_repo.py +++ b/rhodecode/api/tests/test_remove_field_from_repo.py @@ -29,36 +29,35 @@ class TestRemoveFieldFromRepo(object): repo_name = repo.repo_name id_, params = build_data( - self.apikey, 'add_field_to_repo', + self.apikey, + "add_field_to_repo", repoid=repo_name, - key='extra_field', - label='extra_field_label', - description='extra_field_desc') + key="extra_field", + label="extra_field_label", + description="extra_field_desc", + ) response = api_call(self.app, params) expected = { - 'msg': 'Added new repository field `extra_field`', - 'success': True, + "msg": "Added new repository field `extra_field`", + "success": True, } assert_ok(id_, expected, given=response.body) repo = Repository.get_by_repo_name(repo_name) - repo_field = RepositoryField.get_by_key_name('extra_field', repo) + repo_field = RepositoryField.get_by_key_name("extra_field", repo) _data = repo_field.get_dict() - assert _data['field_desc'] == 'extra_field_desc' - assert _data['field_key'] == 'extra_field' - assert _data['field_label'] == 'extra_field_label' + assert _data["field_desc"] == "extra_field_desc" + assert _data["field_key"] == "extra_field" + assert _data["field_label"] == "extra_field_label" - id_, params = build_data( - self.apikey, 'remove_field_from_repo', - repoid=repo_name, - key='extra_field') + id_, params = build_data(self.apikey, "remove_field_from_repo", repoid=repo_name, key="extra_field") response = api_call(self.app, params) expected = { - 'msg': 'Deleted repository field `extra_field`', - 'success': True, + "msg": "Deleted repository field `extra_field`", + "success": True, } assert_ok(id_, expected, given=response.body) repo = Repository.get_by_repo_name(repo_name) - repo_field = RepositoryField.get_by_key_name('extra_field', repo) + repo_field = RepositoryField.get_by_key_name("extra_field", repo) assert repo_field is None diff --git a/rhodecode/api/tests/test_remove_user_from_user_group.py b/rhodecode/api/tests/test_remove_user_from_user_group.py index 87be2df3..e6f4a80d 100644 --- a/rhodecode/api/tests/test_remove_user_from_user_group.py +++ b/rhodecode/api/tests/test_remove_user_from_user_group.py @@ -20,8 +20,7 @@ import mock import pytest from rhodecode.model.user_group import UserGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") @@ -31,26 +30,19 @@ class TestRemoveUserFromUserGroup(object): user_name = user.username group_name = group.users_group_name id_, params = build_data( - self.apikey, 'remove_user_from_user_group', - usergroupid=group_name, - userid=user.username) + self.apikey, "remove_user_from_user_group", usergroupid=group_name, userid=user.username + ) response = api_call(self.app, params) - expected = { - 'msg': 'removed member `%s` from user group `%s`' % ( - user_name, group_name - ), - 'success': True} + expected = {"msg": "removed member `%s` from user group `%s`" % (user_name, group_name), "success": True} assert_ok(id_, expected, given=response.body) - @mock.patch.object(UserGroupModel, 'remove_user_from_group', crash) - def test_api_remove_user_from_user_group_exception_occurred( - self, user_util): + @mock.patch.object(UserGroupModel, "remove_user_from_group", crash) + def test_api_remove_user_from_user_group_exception_occurred(self, user_util): user, group = user_util.create_user_with_group() id_, params = build_data( - self.apikey, 'remove_user_from_user_group', - usergroupid=group.users_group_name, userid=user.username) + self.apikey, "remove_user_from_user_group", usergroupid=group.users_group_name, userid=user.username + ) response = api_call(self.app, params) - expected = 'failed to remove member from user group `%s`' % ( - group.users_group_name) + expected = "failed to remove member from user group `%s`" % (group.users_group_name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_repo_locking.py b/rhodecode/api/tests/test_repo_locking.py index c0077f62..bc9e504c 100644 --- a/rhodecode/api/tests/test_repo_locking.py +++ b/rhodecode/api/tests/test_repo_locking.py @@ -24,8 +24,7 @@ from rhodecode.model.db import Repository from rhodecode.model.user import UserModel from rhodecode.lib.ext_json import json from rhodecode.lib.utils2 import time_to_datetime -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash from rhodecode.tests import TEST_USER_ADMIN_LOGIN @@ -33,39 +32,35 @@ from rhodecode.tests import TEST_USER_ADMIN_LOGIN class TestLock(object): def test_api_lock_repo_lock_aquire(self, backend): id_, params = build_data( - self.apikey, 'lock', - userid=TEST_USER_ADMIN_LOGIN, - repoid=backend.repo_name, - locked=True) + self.apikey, "lock", userid=TEST_USER_ADMIN_LOGIN, repoid=backend.repo_name, locked=True + ) response = api_call(self.app, params) expected = { - 'repo': backend.repo_name, 'locked': True, - 'locked_since': response.json['result']['locked_since'], - 'locked_by': TEST_USER_ADMIN_LOGIN, - 'lock_state_changed': True, - 'lock_reason': Repository.LOCK_API, - 'msg': ('User `%s` set lock state for repo `%s` to `%s`' - % (TEST_USER_ADMIN_LOGIN, backend.repo_name, True)) + "repo": backend.repo_name, + "locked": True, + "locked_since": response.json["result"]["locked_since"], + "locked_by": TEST_USER_ADMIN_LOGIN, + "lock_state_changed": True, + "lock_reason": Repository.LOCK_API, + "msg": ( + "User `%s` set lock state for repo `%s` to `%s`" % (TEST_USER_ADMIN_LOGIN, backend.repo_name, True) + ), } assert_ok(id_, expected, given=response.body) def test_repo_lock_aquire_by_non_admin(self, backend): repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN) repo_name = repo.repo_name - id_, params = build_data( - self.apikey_regular, 'lock', - repoid=repo_name, - locked=True) + id_, params = build_data(self.apikey_regular, "lock", repoid=repo_name, locked=True) response = api_call(self.app, params) expected = { - 'repo': repo_name, - 'locked': True, - 'locked_since': response.json['result']['locked_since'], - 'locked_by': self.TEST_USER_LOGIN, - 'lock_state_changed': True, - 'lock_reason': Repository.LOCK_API, - 'msg': ('User `%s` set lock state for repo `%s` to `%s`' - % (self.TEST_USER_LOGIN, repo_name, True)) + "repo": repo_name, + "locked": True, + "locked_since": response.json["result"]["locked_since"], + "locked_by": self.TEST_USER_LOGIN, + "lock_state_changed": True, + "lock_reason": Repository.LOCK_API, + "msg": ("User `%s` set lock state for repo `%s` to `%s`" % (self.TEST_USER_LOGIN, repo_name, True)), } assert_ok(id_, expected, given=response.body) @@ -73,58 +68,50 @@ class TestLock(object): repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN) repo_name = repo.repo_name id_, params = build_data( - self.apikey_regular, 'lock', - userid=TEST_USER_ADMIN_LOGIN, - repoid=repo_name, - locked=True) + self.apikey_regular, "lock", userid=TEST_USER_ADMIN_LOGIN, repoid=repo_name, locked=True + ) response = api_call(self.app, params) - expected = 'userid is not the same as your user' + expected = "userid is not the same as your user" assert_error(id_, expected, given=response.body) def test_api_lock_repo_lock_aquire_non_admin_not_his_repo(self, backend): - id_, params = build_data( - self.apikey_regular, 'lock', - repoid=backend.repo_name, - locked=True) + id_, params = build_data(self.apikey_regular, "lock", repoid=backend.repo_name, locked=True) response = api_call(self.app, params) - expected = 'repository `%s` does not exist' % (backend.repo_name, ) + expected = "repository `%s` does not exist" % (backend.repo_name,) assert_error(id_, expected, given=response.body) def test_api_lock_repo_lock_release(self, backend): id_, params = build_data( - self.apikey, 'lock', - userid=TEST_USER_ADMIN_LOGIN, - repoid=backend.repo_name, - locked=False) + self.apikey, "lock", userid=TEST_USER_ADMIN_LOGIN, repoid=backend.repo_name, locked=False + ) response = api_call(self.app, params) expected = { - 'repo': backend.repo_name, - 'locked': False, - 'locked_since': None, - 'locked_by': TEST_USER_ADMIN_LOGIN, - 'lock_state_changed': True, - 'lock_reason': Repository.LOCK_API, - 'msg': ('User `%s` set lock state for repo `%s` to `%s`' - % (TEST_USER_ADMIN_LOGIN, backend.repo_name, False)) + "repo": backend.repo_name, + "locked": False, + "locked_since": None, + "locked_by": TEST_USER_ADMIN_LOGIN, + "lock_state_changed": True, + "lock_reason": Repository.LOCK_API, + "msg": ( + "User `%s` set lock state for repo `%s` to `%s`" % (TEST_USER_ADMIN_LOGIN, backend.repo_name, False) + ), } assert_ok(id_, expected, given=response.body) def test_api_lock_repo_lock_aquire_optional_userid(self, backend): - id_, params = build_data( - self.apikey, 'lock', - repoid=backend.repo_name, - locked=True) + id_, params = build_data(self.apikey, "lock", repoid=backend.repo_name, locked=True) response = api_call(self.app, params) - time_ = response.json['result']['locked_since'] + time_ = response.json["result"]["locked_since"] expected = { - 'repo': backend.repo_name, - 'locked': True, - 'locked_since': time_, - 'locked_by': TEST_USER_ADMIN_LOGIN, - 'lock_state_changed': True, - 'lock_reason': Repository.LOCK_API, - 'msg': ('User `%s` set lock state for repo `%s` to `%s`' - % (TEST_USER_ADMIN_LOGIN, backend.repo_name, True)) + "repo": backend.repo_name, + "locked": True, + "locked_since": time_, + "locked_by": TEST_USER_ADMIN_LOGIN, + "lock_state_changed": True, + "lock_reason": Repository.LOCK_API, + "msg": ( + "User `%s` set lock state for repo `%s` to `%s`" % (TEST_USER_ADMIN_LOGIN, backend.repo_name, True) + ), } assert_ok(id_, expected, given=response.body) @@ -135,19 +122,20 @@ class TestLock(object): user = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) Repository.lock(repo, user.user_id, lock_reason=Repository.LOCK_API) - id_, params = build_data(self.apikey, 'lock', repoid=backend.repo_name) + id_, params = build_data(self.apikey, "lock", repoid=backend.repo_name) response = api_call(self.app, params) - time_ = response.json['result']['locked_since'] + time_ = response.json["result"]["locked_since"] expected = { - 'repo': backend.repo_name, - 'locked': True, - 'locked_since': time_, - 'locked_by': TEST_USER_ADMIN_LOGIN, - 'lock_state_changed': False, - 'lock_reason': Repository.LOCK_API, - 'msg': ('Repo `%s` locked by `%s` on `%s`.' - % (backend.repo_name, TEST_USER_ADMIN_LOGIN, - json.dumps(time_to_datetime(time_)))) + "repo": backend.repo_name, + "locked": True, + "locked_since": time_, + "locked_by": TEST_USER_ADMIN_LOGIN, + "lock_state_changed": False, + "lock_reason": Repository.LOCK_API, + "msg": ( + "Repo `%s` locked by `%s` on `%s`." + % (backend.repo_name, TEST_USER_ADMIN_LOGIN, json.dumps(time_to_datetime(time_))) + ), } assert_ok(id_, expected, given=response.body) @@ -155,28 +143,25 @@ class TestLock(object): repo = backend.create_repo(cur_user=self.TEST_USER_LOGIN) repo_name = repo.repo_name assert repo.locked == [None, None, None] - id_, params = build_data(self.apikey, 'lock', repoid=repo.repo_id) + id_, params = build_data(self.apikey, "lock", repoid=repo.repo_id) response = api_call(self.app, params) expected = { - 'repo': repo_name, - 'locked': False, - 'locked_since': None, - 'locked_by': None, - 'lock_state_changed': False, - 'lock_reason': None, - 'msg': ('Repo `%s` not locked.' % (repo_name,)) + "repo": repo_name, + "locked": False, + "locked_since": None, + "locked_by": None, + "lock_state_changed": False, + "lock_reason": None, + "msg": ("Repo `%s` not locked." % (repo_name,)), } assert_ok(id_, expected, given=response.body) - @mock.patch.object(Repository, 'lock', crash) + @mock.patch.object(Repository, "lock", crash) def test_api_lock_error(self, backend): id_, params = build_data( - self.apikey, 'lock', - userid=TEST_USER_ADMIN_LOGIN, - repoid=backend.repo_name, - locked=True) + self.apikey, "lock", userid=TEST_USER_ADMIN_LOGIN, repoid=backend.repo_name, locked=True + ) response = api_call(self.app, params) - expected = 'Error occurred locking repository `%s`' % ( - backend.repo_name,) + expected = "Error occurred locking repository `%s`" % (backend.repo_name,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_rescan_repos.py b/rhodecode/api/tests/test_rescan_repos.py index 36f2401f..b0791df3 100644 --- a/rhodecode/api/tests/test_rescan_repos.py +++ b/rhodecode/api/tests/test_rescan_repos.py @@ -19,24 +19,26 @@ import mock import pytest -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash @pytest.mark.usefixtures("testuser_api", "app") class TestRescanRepos(object): def test_api_rescan_repos(self): - id_, params = build_data(self.apikey, 'rescan_repos') + id_, params = build_data(self.apikey, "rescan_repos") response = api_call(self.app, params) - expected = {'added': [], 'errors': []} + expected = {"added": [], "errors": []} assert_ok(id_, expected, given=response.body) def test_api_rescan_repos_error(self): - id_, params = build_data(self.apikey, 'rescan_repos', ) + id_, params = build_data( + self.apikey, + "rescan_repos", + ) - with mock.patch('rhodecode.lib.utils.repo2db_mapper', side_effect=crash): + with mock.patch("rhodecode.lib.utils.repo2db_mapper", side_effect=crash): response = api_call(self.app, params) - expected = 'Error occurred during rescan repositories action' + expected = "Error occurred during rescan repositories action" assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_revoke_user_group_permission.py b/rhodecode/api/tests/test_revoke_user_group_permission.py index d6d019f0..d3f22ca2 100644 --- a/rhodecode/api/tests/test_revoke_user_group_permission.py +++ b/rhodecode/api/tests/test_revoke_user_group_permission.py @@ -20,8 +20,7 @@ import mock import pytest from rhodecode.model.repo import RepoModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") @@ -29,37 +28,34 @@ class TestRevokeUserGroupPermission(object): def test_api_revoke_user_group_permission(self, backend, user_util): repo = backend.create_repo() user_group = user_util.create_user_group() - user_util.grant_user_group_permission_to_repo( - repo, user_group, 'repository.read') + user_util.grant_user_group_permission_to_repo(repo, user_group, "repository.read") id_, params = build_data( self.apikey, - 'revoke_user_group_permission', + "revoke_user_group_permission", repoid=backend.repo_name, - usergroupid=user_group.users_group_name) + usergroupid=user_group.users_group_name, + ) response = api_call(self.app, params) expected = { - 'msg': 'Revoked perm for user group: `%s` in repo: `%s`' % ( - user_group.users_group_name, backend.repo_name - ), - 'success': True + "msg": "Revoked perm for user group: `%s` in repo: `%s`" % (user_group.users_group_name, backend.repo_name), + "success": True, } assert_ok(id_, expected, given=response.body) - @mock.patch.object(RepoModel, 'revoke_user_group_permission', crash) - def test_api_revoke_user_group_permission_exception_when_adding( - self, backend, user_util): + @mock.patch.object(RepoModel, "revoke_user_group_permission", crash) + def test_api_revoke_user_group_permission_exception_when_adding(self, backend, user_util): user_group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'revoke_user_group_permission', + "revoke_user_group_permission", repoid=backend.repo_name, - usergroupid=user_group.users_group_name) + usergroupid=user_group.users_group_name, + ) response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user group: `%s` in repo: `%s`' % ( - user_group.users_group_name, backend.repo_name - ) + expected = "failed to edit permission for user group: `%s` in repo: `%s`" % ( + user_group.users_group_name, + backend.repo_name, ) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_revoke_user_group_permission_from_repo_group.py b/rhodecode/api/tests/test_revoke_user_group_permission_from_repo_group.py index 9a69a6a4..d57cb454 100644 --- a/rhodecode/api/tests/test_revoke_user_group_permission_from_repo_group.py +++ b/rhodecode/api/tests/test_revoke_user_group_permission_from_repo_group.py @@ -21,107 +21,102 @@ import pytest from rhodecode.model.repo_group import RepoGroupModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestRevokeUserGroupPermissionFromRepoGroup(object): - @pytest.mark.parametrize("name, apply_to_children", [ - ('none', 'none'), - ('all', 'all'), - ('repos', 'repos'), - ('groups', 'groups'), - ]) - def test_api_revoke_user_group_permission_from_repo_group( - self, name, apply_to_children, user_util): + @pytest.mark.parametrize( + "name, apply_to_children", + [ + ("none", "none"), + ("all", "all"), + ("repos", "repos"), + ("groups", "groups"), + ], + ) + def test_api_revoke_user_group_permission_from_repo_group(self, name, apply_to_children, user_util): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() - user_util.grant_user_group_permission_to_repo_group( - repo_group, user_group, 'group.read') + user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, "group.read") id_, params = build_data( - self.apikey, 'revoke_user_group_permission_from_repo_group', + self.apikey, + "revoke_user_group_permission_from_repo_group", repogroupid=repo_group.name, usergroupid=user_group.users_group_name, - apply_to_children=apply_to_children,) + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) expected = { - 'msg': ( - 'Revoked perm (recursive:%s) for user group: `%s`' - ' in repo group: `%s`' % ( - apply_to_children, user_group.users_group_name, - repo_group.name - ) + "msg": ( + "Revoked perm (recursive:%s) for user group: `%s`" + " in repo group: `%s`" % (apply_to_children, user_group.users_group_name, repo_group.name) ), - 'success': True + "success": True, } assert_ok(id_, expected, given=response.body) @pytest.mark.parametrize( - "name, apply_to_children, grant_admin, access_ok", [ - ('none', 'none', False, False), - ('all', 'all', False, False), - ('repos', 'repos', False, False), - ('groups', 'groups', False, False), - + "name, apply_to_children, grant_admin, access_ok", + [ + ("none", "none", False, False), + ("all", "all", False, False), + ("repos", "repos", False, False), + ("groups", "groups", False, False), # after granting admin rights - ('none', 'none', False, False), - ('all', 'all', False, False), - ('repos', 'repos', False, False), - ('groups', 'groups', False, False), - ] + ("none", "none", False, False), + ("all", "all", False, False), + ("repos", "repos", False, False), + ("groups", "groups", False, False), + ], ) def test_api_revoke_user_group_permission_from_repo_group_by_regular_user( - self, name, apply_to_children, grant_admin, access_ok, user_util): + self, name, apply_to_children, grant_admin, access_ok, user_util + ): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() - user_util.grant_user_group_permission_to_repo_group( - repo_group, user_group, 'group.read') + user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, "group.read") if grant_admin: - user_util.grant_user_permission_to_repo_group( - repo_group.name, self.TEST_USER_LOGIN, 'group.admin') + user_util.grant_user_permission_to_repo_group(repo_group.name, self.TEST_USER_LOGIN, "group.admin") id_, params = build_data( self.apikey_regular, - 'revoke_user_group_permission_from_repo_group', + "revoke_user_group_permission_from_repo_group", repogroupid=repo_group.name, usergroupid=user_group.users_group_name, - apply_to_children=apply_to_children,) + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) if access_ok: expected = { - 'msg': ( - 'Revoked perm (recursive:%s) for user group: `%s`' - ' in repo group: `%s`' % ( - apply_to_children, TEST_USER_ADMIN_LOGIN, - repo_group.name - ) + "msg": ( + "Revoked perm (recursive:%s) for user group: `%s`" + " in repo group: `%s`" % (apply_to_children, TEST_USER_ADMIN_LOGIN, repo_group.name) ), - 'success': True + "success": True, } assert_ok(id_, expected, given=response.body) else: - expected = 'repository group `%s` does not exist' % ( - repo_group.name,) + expected = "repository group `%s` does not exist" % (repo_group.name,) assert_error(id_, expected, given=response.body) - @mock.patch.object(RepoGroupModel, 'revoke_user_group_permission', crash) - def test_api_revoke_user_group_permission_from_repo_group_exception_on_add( - self, user_util): + @mock.patch.object(RepoGroupModel, "revoke_user_group_permission", crash) + def test_api_revoke_user_group_permission_from_repo_group_exception_on_add(self, user_util): user_group = user_util.create_user_group() repo_group = user_util.create_repo_group() id_, params = build_data( - self.apikey, 'revoke_user_group_permission_from_repo_group', + self.apikey, + "revoke_user_group_permission_from_repo_group", repogroupid=repo_group.name, - usergroupid=user_group.users_group_name) + usergroupid=user_group.users_group_name, + ) response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user group: `%s`' - ' in repo group: `%s`' % ( - user_group.users_group_name, repo_group.name) + expected = "failed to edit permission for user group: `%s` in repo group: `%s`" % ( + user_group.users_group_name, + repo_group.name, ) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_revoke_user_group_permission_from_user_group.py b/rhodecode/api/tests/test_revoke_user_group_permission_from_user_group.py index 3e767b65..e3d0b48b 100644 --- a/rhodecode/api/tests/test_revoke_user_group_permission_from_user_group.py +++ b/rhodecode/api/tests/test_revoke_user_group_permission_from_user_group.py @@ -24,33 +24,34 @@ from rhodecode.api.tests.utils import build_data, api_call, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestRevokeUserGroupPermissionFromUserGroup(object): - @pytest.mark.parametrize("name", [ - ('none',), - ('all',), - ('repos',), - ('groups',), - ]) - def test_api_revoke_user_group_permission_from_user_group( - self, name, user_util): + @pytest.mark.parametrize( + "name", + [ + ("none",), + ("all",), + ("repos",), + ("groups",), + ], + ) + def test_api_revoke_user_group_permission_from_user_group(self, name, user_util): user = UserModel().get_by_username(self.TEST_USER_LOGIN) group = user_util.create_user_group() source_group = user_util.create_user_group() - user_util.grant_user_permission_to_user_group( - group, user, 'usergroup.read') - user_util.grant_user_group_permission_to_user_group( - source_group, group, 'usergroup.read') + user_util.grant_user_permission_to_user_group(group, user, "usergroup.read") + user_util.grant_user_group_permission_to_user_group(source_group, group, "usergroup.read") id_, params = build_data( - self.apikey, 'revoke_user_group_permission_from_user_group', + self.apikey, + "revoke_user_group_permission_from_user_group", usergroupid=group.users_group_name, - sourceusergroupid=source_group.users_group_name) + sourceusergroupid=source_group.users_group_name, + ) response = api_call(self.app, params) expected = { - 'msg': 'Revoked perm for user group: `%s` in user group: `%s`' % ( - source_group.users_group_name, group.users_group_name - ), - 'success': True + "msg": "Revoked perm for user group: `%s` in user group: `%s`" + % (source_group.users_group_name, group.users_group_name), + "success": True, } assert_ok(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_revoke_user_permission.py b/rhodecode/api/tests/test_revoke_user_permission.py index 49580772..7a1efa5e 100644 --- a/rhodecode/api/tests/test_revoke_user_permission.py +++ b/rhodecode/api/tests/test_revoke_user_permission.py @@ -20,8 +20,7 @@ import mock import pytest from rhodecode.model.repo import RepoModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") @@ -29,36 +28,22 @@ class TestRevokeUserPermission(object): def test_api_revoke_user_permission(self, backend, user_util): repo = backend.create_repo() user = user_util.create_user() - user_util.grant_user_permission_to_repo( - repo, user, 'repository.read') + user_util.grant_user_permission_to_repo(repo, user, "repository.read") - id_, params = build_data( - self.apikey, - 'revoke_user_permission', - repoid=repo.repo_name, - userid=user.username) + id_, params = build_data(self.apikey, "revoke_user_permission", repoid=repo.repo_name, userid=user.username) response = api_call(self.app, params) expected = { - 'msg': 'Revoked perm for user: `%s` in repo: `%s`' % ( - user.username, backend.repo_name - ), - 'success': True + "msg": "Revoked perm for user: `%s` in repo: `%s`" % (user.username, backend.repo_name), + "success": True, } assert_ok(id_, expected, given=response.body) - @mock.patch.object(RepoModel, 'revoke_user_permission', crash) - def test_api_revoke_user_permission_exception_when_adding( - self, backend, user_util): + @mock.patch.object(RepoModel, "revoke_user_permission", crash) + def test_api_revoke_user_permission_exception_when_adding(self, backend, user_util): user = user_util.create_user() - id_, params = build_data( - self.apikey, - 'revoke_user_permission', - repoid=backend.repo_name, - userid=user.username) + id_, params = build_data(self.apikey, "revoke_user_permission", repoid=backend.repo_name, userid=user.username) response = api_call(self.app, params) - expected = 'failed to edit permission for user: `%s` in repo: `%s`' % ( - user.username, backend.repo_name - ) + expected = "failed to edit permission for user: `%s` in repo: `%s`" % (user.username, backend.repo_name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_revoke_user_permission_from_repo_group.py b/rhodecode/api/tests/test_revoke_user_permission_from_repo_group.py index 3bc12bac..02e4f65d 100644 --- a/rhodecode/api/tests/test_revoke_user_permission_from_repo_group.py +++ b/rhodecode/api/tests/test_revoke_user_permission_from_repo_group.py @@ -20,105 +20,94 @@ import mock import pytest from rhodecode.model.repo_group import RepoGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestRevokeUserPermissionFromRepoGroup(object): - @pytest.mark.parametrize("name, apply_to_children", [ - ('none', 'none'), - ('all', 'all'), - ('repos', 'repos'), - ('groups', 'groups'), - ]) - def test_api_revoke_user_permission_from_repo_group( - self, name, apply_to_children, user_util): + @pytest.mark.parametrize( + "name, apply_to_children", + [ + ("none", "none"), + ("all", "all"), + ("repos", "repos"), + ("groups", "groups"), + ], + ) + def test_api_revoke_user_permission_from_repo_group(self, name, apply_to_children, user_util): user = user_util.create_user() repo_group = user_util.create_repo_group() - user_util.grant_user_permission_to_repo_group( - repo_group, user, 'group.read') + user_util.grant_user_permission_to_repo_group(repo_group, user, "group.read") id_, params = build_data( self.apikey, - 'revoke_user_permission_from_repo_group', + "revoke_user_permission_from_repo_group", repogroupid=repo_group.name, userid=user.username, - apply_to_children=apply_to_children,) + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) expected = { - 'msg': ( - 'Revoked perm (recursive:%s) for user: `%s`' - ' in repo group: `%s`' % ( - apply_to_children, user.username, repo_group.name - ) + "msg": ( + "Revoked perm (recursive:%s) for user: `%s`" + " in repo group: `%s`" % (apply_to_children, user.username, repo_group.name) ), - 'success': True + "success": True, } assert_ok(id_, expected, given=response.body) @pytest.mark.parametrize( - "name, apply_to_children, grant_admin, access_ok", [ - ('none', 'none', False, False), - ('all', 'all', False, False), - ('repos', 'repos', False, False), - ('groups', 'groups', False, False), - + "name, apply_to_children, grant_admin, access_ok", + [ + ("none", "none", False, False), + ("all", "all", False, False), + ("repos", "repos", False, False), + ("groups", "groups", False, False), # after granting admin rights - ('none', 'none', False, False), - ('all', 'all', False, False), - ('repos', 'repos', False, False), - ('groups', 'groups', False, False), - ] + ("none", "none", False, False), + ("all", "all", False, False), + ("repos", "repos", False, False), + ("groups", "groups", False, False), + ], ) def test_api_revoke_user_permission_from_repo_group_by_regular_user( - self, name, apply_to_children, grant_admin, access_ok, user_util): + self, name, apply_to_children, grant_admin, access_ok, user_util + ): user = user_util.create_user() repo_group = user_util.create_repo_group() - permission = 'group.admin' if grant_admin else 'group.read' - user_util.grant_user_permission_to_repo_group( - repo_group, user, permission) + permission = "group.admin" if grant_admin else "group.read" + user_util.grant_user_permission_to_repo_group(repo_group, user, permission) id_, params = build_data( self.apikey_regular, - 'revoke_user_permission_from_repo_group', + "revoke_user_permission_from_repo_group", repogroupid=repo_group.name, userid=user.username, - apply_to_children=apply_to_children,) + apply_to_children=apply_to_children, + ) response = api_call(self.app, params) if access_ok: expected = { - 'msg': ( - 'Revoked perm (recursive:%s) for user: `%s`' - ' in repo group: `%s`' % ( - apply_to_children, user.username, repo_group.name - ) + "msg": ( + "Revoked perm (recursive:%s) for user: `%s`" + " in repo group: `%s`" % (apply_to_children, user.username, repo_group.name) ), - 'success': True + "success": True, } assert_ok(id_, expected, given=response.body) else: - expected = 'repository group `%s` does not exist' % ( - repo_group.name) + expected = "repository group `%s` does not exist" % (repo_group.name) assert_error(id_, expected, given=response.body) - @mock.patch.object(RepoGroupModel, 'revoke_user_permission', crash) - def test_api_revoke_user_permission_from_repo_group_exception_when_adding( - self, user_util): + @mock.patch.object(RepoGroupModel, "revoke_user_permission", crash) + def test_api_revoke_user_permission_from_repo_group_exception_when_adding(self, user_util): user = user_util.create_user() repo_group = user_util.create_repo_group() id_, params = build_data( - self.apikey, - 'revoke_user_permission_from_repo_group', - repogroupid=repo_group.name, - userid=user.username + self.apikey, "revoke_user_permission_from_repo_group", repogroupid=repo_group.name, userid=user.username ) response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user: `%s` in repo group: `%s`' % ( - user.username, repo_group.name - ) - ) + expected = "failed to edit permission for user: `%s` in repo group: `%s`" % (user.username, repo_group.name) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_revoke_user_permission_from_user_group.py b/rhodecode/api/tests/test_revoke_user_permission_from_user_group.py index 978ea9d7..776fbc14 100644 --- a/rhodecode/api/tests/test_revoke_user_permission_from_user_group.py +++ b/rhodecode/api/tests/test_revoke_user_permission_from_user_group.py @@ -20,91 +20,90 @@ import mock import pytest from rhodecode.model.user_group import UserGroupModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash @pytest.mark.usefixtures("testuser_api", "app") class TestRevokeUserPermissionFromUserGroup(object): - @pytest.mark.parametrize("name", [ - ('none',), - ('all',), - ('repos',), - ('groups',), - ]) + @pytest.mark.parametrize( + "name", + [ + ("none",), + ("all",), + ("repos",), + ("groups",), + ], + ) def test_api_revoke_user_permission_from_user_group(self, name, user_util): user = user_util.create_user() group = user_util.create_user_group() - user_util.grant_user_permission_to_user_group( - group, user, 'usergroup.admin') + user_util.grant_user_permission_to_user_group(group, user, "usergroup.admin") id_, params = build_data( self.apikey, - 'revoke_user_permission_from_user_group', + "revoke_user_permission_from_user_group", usergroupid=group.users_group_name, - userid=user.username) + userid=user.username, + ) response = api_call(self.app, params) expected = { - 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % ( - user.username, group.users_group_name - ), - 'success': True + "msg": "Revoked perm for user: `%s` in user group: `%s`" % (user.username, group.users_group_name), + "success": True, } assert_ok(id_, expected, given=response.body) - @pytest.mark.parametrize("name, grant_admin, access_ok", [ - ('none', False, False), - ('all', False, False), - ('repos', False, False), - ('groups', False, False), - - # after granting admin rights - ('none', False, False), - ('all', False, False), - ('repos', False, False), - ('groups', False, False), - ]) - def test_api_revoke_user_permission_from_user_group_by_regular_user( - self, name, grant_admin, access_ok, user_util): + @pytest.mark.parametrize( + "name, grant_admin, access_ok", + [ + ("none", False, False), + ("all", False, False), + ("repos", False, False), + ("groups", False, False), + # after granting admin rights + ("none", False, False), + ("all", False, False), + ("repos", False, False), + ("groups", False, False), + ], + ) + def test_api_revoke_user_permission_from_user_group_by_regular_user(self, name, grant_admin, access_ok, user_util): user = user_util.create_user() group = user_util.create_user_group() - permission = 'usergroup.admin' if grant_admin else 'usergroup.read' + permission = "usergroup.admin" if grant_admin else "usergroup.read" user_util.grant_user_permission_to_user_group(group, user, permission) id_, params = build_data( self.apikey_regular, - 'revoke_user_permission_from_user_group', + "revoke_user_permission_from_user_group", usergroupid=group.users_group_name, - userid=user.username) + userid=user.username, + ) response = api_call(self.app, params) if access_ok: expected = { - 'msg': 'Revoked perm for user: `%s` in user group: `%s`' % ( - user.username, group.users_group_name - ), - 'success': True + "msg": "Revoked perm for user: `%s` in user group: `%s`" % (user.username, group.users_group_name), + "success": True, } assert_ok(id_, expected, given=response.body) else: - expected = 'user group `%s` does not exist' % ( - group.users_group_name) + expected = "user group `%s` does not exist" % (group.users_group_name) assert_error(id_, expected, given=response.body) - @mock.patch.object(UserGroupModel, 'revoke_user_permission', crash) - def test_api_revoke_user_permission_from_user_group_exception_when_adding( - self, user_util): + @mock.patch.object(UserGroupModel, "revoke_user_permission", crash) + def test_api_revoke_user_permission_from_user_group_exception_when_adding(self, user_util): user = user_util.create_user() group = user_util.create_user_group() id_, params = build_data( self.apikey, - 'revoke_user_permission_from_user_group', + "revoke_user_permission_from_user_group", usergroupid=group.users_group_name, - userid=user.username) + userid=user.username, + ) response = api_call(self.app, params) - expected = ( - 'failed to edit permission for user: `%s` in user group: `%s`' % ( - user.username, group.users_group_name) + expected = "failed to edit permission for user: `%s` in user group: `%s`" % ( + user.username, + group.users_group_name, ) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_service_api.py b/rhodecode/api/tests/test_service_api.py index b47bc735..83e35d50 100644 --- a/rhodecode/api/tests/test_service_api.py +++ b/rhodecode/api/tests/test_service_api.py @@ -18,37 +18,38 @@ import pytest -from rhodecode.api.tests.utils import ( - build_data, api_call) +from rhodecode.api.tests.utils import build_data, api_call @pytest.mark.usefixtures("app") class TestServiceApi: - def test_service_api_with_wrong_secret(self): - id, payload = build_data("wrong_api_key", 'service_get_repo_name_by_id') + id, payload = build_data("wrong_api_key", "service_get_repo_name_by_id") response = api_call(self.app, payload) - assert 'Invalid API KEY' == response.json['error'] + assert "Invalid API KEY" == response.json["error"] def test_service_api_with_legit_secret(self): - id, payload = build_data(self.app.app.config.get_settings()['app.service_api.token'], - 'service_get_repo_name_by_id', repo_id='1') + id, payload = build_data( + self.app.app.config.get_settings()["app.service_api.token"], "service_get_repo_name_by_id", repo_id="1" + ) response = api_call(self.app, payload) - assert not response.json['error'] + assert not response.json["error"] def test_service_api_not_a_part_of_public_api_suggestions(self): - id, payload = build_data("secret", 'some_random_guess_method') + id, payload = build_data("secret", "some_random_guess_method") response = api_call(self.app, payload) - assert 'service_' not in response.json['error'] + assert "service_" not in response.json["error"] def test_service_get_data_for_ssh_wrapper_output(self): id, payload = build_data( - self.app.app.config.get_settings()['app.service_api.token'], - 'service_get_data_for_ssh_wrapper', + self.app.app.config.get_settings()["app.service_api.token"], + "service_get_data_for_ssh_wrapper", user_id=1, - repo_name='vcs_test_git') + repo_name="vcs_test_git", + ) response = api_call(self.app, payload) - assert ['branch_permissions', 'repo_permissions', 'repos_path', 'user_id', 'username']\ - == list(response.json['result'].keys()) + assert ["branch_permissions", "repo_permissions", "repos_path", "user_id", "username"] == list( + response.json["result"].keys() + ) diff --git a/rhodecode/api/tests/test_store_exception.py b/rhodecode/api/tests/test_store_exception.py index dfa7c035..4523f3d9 100644 --- a/rhodecode/api/tests/test_store_exception.py +++ b/rhodecode/api/tests/test_store_exception.py @@ -24,34 +24,26 @@ from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_er @pytest.mark.usefixtures("testuser_api", "app") class TestStoreException(object): - def test_store_exception_invalid_json(self): - id_, params = build_data(self.apikey, 'store_exception', - exc_data_json='XXX,{') + id_, params = build_data(self.apikey, "store_exception", exc_data_json="XXX,{") response = api_call(self.app, params) - expected = 'Failed to parse JSON data from exc_data_json field. ' \ - 'Please make sure it contains a valid JSON.' + expected = "Failed to parse JSON data from exc_data_json field. Please make sure it contains a valid JSON." assert_error(id_, expected, given=response.body) def test_store_exception_missing_json_params_json(self): - id_, params = build_data(self.apikey, 'store_exception', - exc_data_json='{"foo":"bar"}') + id_, params = build_data(self.apikey, "store_exception", exc_data_json='{"foo":"bar"}') response = api_call(self.app, params) - expected = "Missing exc_traceback, or exc_type_name in " \ - "exc_data_json field. Missing: 'exc_traceback'" + expected = "Missing exc_traceback, or exc_type_name in exc_data_json field. Missing: 'exc_traceback'" assert_error(id_, expected, given=response.body) def test_store_exception(self): id_, params = build_data( - self.apikey, 'store_exception', - exc_data_json='{"exc_traceback": "invalid", "exc_type_name":"ValueError"}') + self.apikey, "store_exception", exc_data_json='{"exc_traceback": "invalid", "exc_type_name":"ValueError"}' + ) response = api_call(self.app, params) - exc_id = response.json['result']['exc_id'] + exc_id = response.json["result"]["exc_id"] - expected = { - 'exc_id': exc_id, - 'exc_url': 'http://example.com/_admin/settings/exceptions/{}'.format(exc_id) - } + expected = {"exc_id": exc_id, "exc_url": "http://example.com/_admin/settings/exceptions/{}".format(exc_id)} assert_ok(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_update_pull_request.py b/rhodecode/api/tests/test_update_pull_request.py index dedd73c7..38876363 100644 --- a/rhodecode/api/tests/test_update_pull_request.py +++ b/rhodecode/api/tests/test_update_pull_request.py @@ -22,70 +22,65 @@ from rhodecode.lib.vcs.nodes import FileNode from rhodecode.model.db import User from rhodecode.model.pull_request import PullRequestModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error @pytest.mark.usefixtures("testuser_api", "app") class TestUpdatePullRequest(object): - @pytest.mark.backends("git", "hg") - def test_api_update_pull_request_title_or_description( - self, pr_util, no_notifications): + def test_api_update_pull_request_title_or_description(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'update_pull_request', + self.apikey, + "update_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - title='New TITLE OF A PR', - description='New DESC OF A PR', + title="New TITLE OF A PR", + description="New DESC OF A PR", ) response = api_call(self.app, params) expected = { - "msg": "Updated pull request `{}`".format( - pull_request.pull_request_id), - "pull_request": response.json['result']['pull_request'], + "msg": "Updated pull request `{}`".format(pull_request.pull_request_id), + "pull_request": response.json["result"]["pull_request"], "updated_commits": {"added": [], "common": [], "removed": []}, "updated_reviewers": {"added": [], "removed": []}, "updated_observers": {"added": [], "removed": []}, } - response_json = response.json['result'] + response_json = response.json["result"] assert response_json == expected - pr = response_json['pull_request'] - assert pr['title'] == 'New TITLE OF A PR' - assert pr['description'] == 'New DESC OF A PR' + pr = response_json["pull_request"] + assert pr["title"] == "New TITLE OF A PR" + assert pr["description"] == "New DESC OF A PR" @pytest.mark.backends("git", "hg") - def test_api_try_update_closed_pull_request( - self, pr_util, no_notifications): + def test_api_try_update_closed_pull_request(self, pr_util, no_notifications): pull_request = pr_util.create_pull_request() - PullRequestModel().close_pull_request( - pull_request, TEST_USER_ADMIN_LOGIN) + PullRequestModel().close_pull_request(pull_request, TEST_USER_ADMIN_LOGIN) id_, params = build_data( - self.apikey, 'update_pull_request', + self.apikey, + "update_pull_request", repoid=pull_request.target_repo.repo_name, - pullrequestid=pull_request.pull_request_id) + pullrequestid=pull_request.pull_request_id, + ) response = api_call(self.app, params) - expected = 'pull request `{}` update failed, pull request ' \ - 'is closed'.format(pull_request.pull_request_id) + expected = "pull request `{}` update failed, pull request is closed".format(pull_request.pull_request_id) assert_error(id_, expected, response.body) @pytest.mark.backends("git", "hg") def test_api_update_update_commits(self, pr_util, no_notifications): commits = [ - {'message': 'a'}, - {'message': 'b', 'added': [FileNode(b'file_b', b'test_content\n')]}, - {'message': 'c', 'added': [FileNode(b'file_c', b'test_content\n')]}, + {"message": "a"}, + {"message": "b", "added": [FileNode(b"file_b", b"test_content\n")]}, + {"message": "c", "added": [FileNode(b"file_c", b"test_content\n")]}, ] - pull_request = pr_util.create_pull_request( - commits=commits, target_head='a', source_head='b', revisions=['b']) - pr_util.update_source_repository(head='c') + pull_request = pr_util.create_pull_request(commits=commits, target_head="a", source_head="b", revisions=["b"]) + pr_util.update_source_repository(head="c") repo = pull_request.source_repo.scm_instance() commits = [x for x in repo.get_commits()] @@ -94,21 +89,23 @@ class TestUpdatePullRequest(object): total_commits = [added_commit_id, common_commit_id] id_, params = build_data( - self.apikey, 'update_pull_request', + self.apikey, + "update_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - update_commits=True + update_commits=True, ) response = api_call(self.app, params) expected = { - "msg": "Updated pull request `{}`".format( - pull_request.pull_request_id), - "pull_request": response.json['result']['pull_request'], - "updated_commits": {"added": [added_commit_id], - "common": [common_commit_id], - "total": total_commits, - "removed": []}, + "msg": "Updated pull request `{}`".format(pull_request.pull_request_id), + "pull_request": response.json["result"]["pull_request"], + "updated_commits": { + "added": [added_commit_id], + "common": [common_commit_id], + "total": total_commits, + "removed": [], + }, "updated_reviewers": {"added": [], "removed": []}, "updated_observers": {"added": [], "removed": []}, } @@ -116,34 +113,31 @@ class TestUpdatePullRequest(object): assert_ok(id_, expected, response.body) @pytest.mark.backends("git", "hg") - def test_api_update_change_reviewers( - self, user_util, pr_util, no_notifications): + def test_api_update_change_reviewers(self, user_util, pr_util, no_notifications): a = user_util.create_user() b = user_util.create_user() c = user_util.create_user() new_reviewers = [ - {'username': b.username, 'reasons': ['updated via API'], - 'mandatory':False}, - {'username': c.username, 'reasons': ['updated via API'], - 'mandatory':False}, + {"username": b.username, "reasons": ["updated via API"], "mandatory": False}, + {"username": c.username, "reasons": ["updated via API"], "mandatory": False}, ] added = [b.username, c.username] removed = [a.username] - pull_request = pr_util.create_pull_request( - reviewers=[(a.username, ['added via API'], False, 'reviewer', [])]) + pull_request = pr_util.create_pull_request(reviewers=[(a.username, ["added via API"], False, "reviewer", [])]) id_, params = build_data( - self.apikey, 'update_pull_request', + self.apikey, + "update_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - reviewers=new_reviewers) + reviewers=new_reviewers, + ) response = api_call(self.app, params) expected = { - "msg": "Updated pull request `{}`".format( - pull_request.pull_request_id), - "pull_request": response.json['result']['pull_request'], + "msg": "Updated pull request `{}`".format(pull_request.pull_request_id), + "pull_request": response.json["result"]["pull_request"], "updated_commits": {"added": [], "common": [], "removed": []}, "updated_reviewers": {"added": added, "removed": removed}, "updated_observers": {"added": [], "removed": []}, @@ -156,13 +150,15 @@ class TestUpdatePullRequest(object): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'update_pull_request', + self.apikey, + "update_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=pull_request.pull_request_id, - reviewers=[{'username': 'bad_name'}]) + reviewers=[{"username": "bad_name"}], + ) response = api_call(self.app, params) - expected = 'user `bad_name` does not exist' + expected = "user `bad_name` does not exist" assert_error(id_, expected, response.body) @@ -170,15 +166,17 @@ class TestUpdatePullRequest(object): def test_api_update_repo_error(self, pr_util): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'update_pull_request', - repoid='fake', + self.apikey, + "update_pull_request", + repoid="fake", pullrequestid=pull_request.pull_request_id, - reviewers=[{'username': 'bad_name'}]) + reviewers=[{"username": "bad_name"}], + ) response = api_call(self.app, params) - expected = 'repository `fake` does not exist' + expected = "repository `fake` does not exist" - response_json = response.json['error'] + response_json = response.json["error"] assert response_json == expected @pytest.mark.backends("git", "hg") @@ -186,28 +184,30 @@ class TestUpdatePullRequest(object): pull_request = pr_util.create_pull_request() id_, params = build_data( - self.apikey, 'update_pull_request', + self.apikey, + "update_pull_request", repoid=pull_request.target_repo.repo_name, pullrequestid=999999, - reviewers=[{'username': 'bad_name'}]) + reviewers=[{"username": "bad_name"}], + ) response = api_call(self.app, params) - expected = 'pull request `999999` does not exist' + expected = "pull request `999999` does not exist" assert_error(id_, expected, response.body) @pytest.mark.backends("git", "hg") - def test_api_update_pull_request_no_perms_to_update( - self, user_util, pr_util): + def test_api_update_pull_request_no_perms_to_update(self, user_util, pr_util): user = user_util.create_user() pull_request = pr_util.create_pull_request() id_, params = build_data( - user.api_key, 'update_pull_request', + user.api_key, + "update_pull_request", repoid=pull_request.target_repo.repo_name, - pullrequestid=pull_request.pull_request_id,) + pullrequestid=pull_request.pull_request_id, + ) response = api_call(self.app, params) - expected = ('pull request `%s` update failed, ' - 'no permission to update.') % pull_request.pull_request_id + expected = ("pull request `%s` update failed, no permission to update.") % pull_request.pull_request_id assert_error(id_, expected, response.body) diff --git a/rhodecode/api/tests/test_update_repo.py b/rhodecode/api/tests/test_update_repo.py index 713fc523..90062ffd 100644 --- a/rhodecode/api/tests/test_update_repo.py +++ b/rhodecode/api/tests/test_update_repo.py @@ -22,85 +22,63 @@ import pytest from rhodecode.model.repo import RepoModel from rhodecode.model.scm import ScmModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash, jsonify) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash, jsonify from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.fixtures.fixture_utils import plain_http_host_only_stub fixture = Fixture() -UPDATE_REPO_NAME = 'api_update_me' +UPDATE_REPO_NAME = "api_update_me" class SAME_AS_UPDATES(object): - """ Constant used for tests below """ + """Constant used for tests below""" @pytest.mark.usefixtures("testuser_api", "app") class TestApiUpdateRepo(object): - - @pytest.mark.parametrize("updates, expected", [ - ({'owner': TEST_USER_REGULAR_LOGIN}, - SAME_AS_UPDATES), - - ({'description': 'new description'}, - SAME_AS_UPDATES), - - ({'clone_uri': 'http://foo.com/repo'}, - SAME_AS_UPDATES), - - ({'clone_uri': None}, - {'clone_uri': ''}), - - ({'clone_uri': ''}, - {'clone_uri': ''}), - - ({'clone_uri': 'http://example.com/repo_pull'}, - {'clone_uri': 'http://example.com/repo_pull'}), - - ({'push_uri': ''}, - {'push_uri': ''}), - - ({'push_uri': 'http://example.com/repo_push'}, - {'push_uri': 'http://example.com/repo_push'}), - - ({'landing_rev': None}, # auto-updated based on type of repo - {'landing_rev': [None, None]}), - - ({'enable_statistics': True}, - SAME_AS_UPDATES), - - ({'enable_locking': True}, - SAME_AS_UPDATES), - - ({'enable_downloads': True}, - SAME_AS_UPDATES), - - ({'repo_name': 'new_repo_name'}, - { - 'repo_name': 'new_repo_name', - 'url': 'http://{}/new_repo_name'.format(plain_http_host_only_stub()) - }), - - ({'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME), - '_group': 'test_group_for_update'}, - { - 'repo_name': 'test_group_for_update/{}'.format(UPDATE_REPO_NAME), - 'url': 'http://{}/test_group_for_update/{}'.format( - plain_http_host_only_stub(), UPDATE_REPO_NAME) - }), - ]) + @pytest.mark.parametrize( + "updates, expected", + [ + ({"owner": TEST_USER_REGULAR_LOGIN}, SAME_AS_UPDATES), + ({"description": "new description"}, SAME_AS_UPDATES), + ({"clone_uri": "http://foo.com/repo"}, SAME_AS_UPDATES), + ({"clone_uri": None}, {"clone_uri": ""}), + ({"clone_uri": ""}, {"clone_uri": ""}), + ({"clone_uri": "http://example.com/repo_pull"}, {"clone_uri": "http://example.com/repo_pull"}), + ({"push_uri": ""}, {"push_uri": ""}), + ({"push_uri": "http://example.com/repo_push"}, {"push_uri": "http://example.com/repo_push"}), + ( + {"landing_rev": None}, # auto-updated based on type of repo + {"landing_rev": [None, None]}, + ), + ({"enable_statistics": True}, SAME_AS_UPDATES), + ({"enable_locking": True}, SAME_AS_UPDATES), + ({"enable_downloads": True}, SAME_AS_UPDATES), + ( + {"repo_name": "new_repo_name"}, + {"repo_name": "new_repo_name", "url": "http://{}/new_repo_name".format(plain_http_host_only_stub())}, + ), + ( + {"repo_name": "test_group_for_update/{}".format(UPDATE_REPO_NAME), "_group": "test_group_for_update"}, + { + "repo_name": "test_group_for_update/{}".format(UPDATE_REPO_NAME), + "url": "http://{}/test_group_for_update/{}".format(plain_http_host_only_stub(), UPDATE_REPO_NAME), + }, + ), + ], + ) def test_api_update_repo(self, updates, expected, backend): repo_name = UPDATE_REPO_NAME repo = fixture.create_repo(repo_name, repo_type=backend.alias) - if updates.get('_group'): - fixture.create_repo_group(updates['_group']) + if updates.get("_group"): + fixture.create_repo_group(updates["_group"]) - if 'landing_rev' in updates: + if "landing_rev" in updates: default_landing_ref, _lbl = ScmModel.backend_landing_ref(backend.alias) - _type, _name = default_landing_ref.split(':') - updates['landing_rev'] = default_landing_ref - expected['landing_rev'] = [_type, _name] + _type, _name = default_landing_ref.split(":") + updates["landing_rev"] = default_landing_ref + expected["landing_rev"] = [_type, _name] expected_api_data = repo.get_api_data(include_secrets=True) if expected is SAME_AS_UPDATES: @@ -108,101 +86,90 @@ class TestApiUpdateRepo(object): else: expected_api_data.update(expected) - id_, params = build_data( - self.apikey, 'update_repo', repoid=repo_name, **updates) + id_, params = build_data(self.apikey, "update_repo", repoid=repo_name, **updates) - with mock.patch('rhodecode.model.validation_schema.validators.url_validator'): + with mock.patch("rhodecode.model.validation_schema.validators.url_validator"): response = api_call(self.app, params) - if updates.get('repo_name'): - repo_name = updates['repo_name'] + if updates.get("repo_name"): + repo_name = updates["repo_name"] try: expected = { - 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo_name), - 'repository': jsonify(expected_api_data) + "msg": "updated repo ID:%s %s" % (repo.repo_id, repo_name), + "repository": jsonify(expected_api_data), } assert_ok(id_, expected, given=response.body) finally: fixture.destroy_repo(repo_name) - if updates.get('_group'): - fixture.destroy_repo_group(updates['_group']) + if updates.get("_group"): + fixture.destroy_repo_group(updates["_group"]) def test_api_update_repo_fork_of_field(self, backend): master_repo = backend.create_repo() repo = backend.create_repo() - updates = { - 'fork_of': master_repo.repo_name, - 'fork_of_id': master_repo.repo_id - } + updates = {"fork_of": master_repo.repo_name, "fork_of_id": master_repo.repo_id} expected_api_data = repo.get_api_data(include_secrets=True) expected_api_data.update(updates) - id_, params = build_data( - self.apikey, 'update_repo', repoid=repo.repo_name, **updates) + id_, params = build_data(self.apikey, "update_repo", repoid=repo.repo_name, **updates) response = api_call(self.app, params) expected = { - 'msg': 'updated repo ID:%s %s' % (repo.repo_id, repo.repo_name), - 'repository': jsonify(expected_api_data) + "msg": "updated repo ID:%s %s" % (repo.repo_id, repo.repo_name), + "repository": jsonify(expected_api_data), } assert_ok(id_, expected, given=response.body) - result = response.json['result']['repository'] - assert result['fork_of'] == master_repo.repo_name - assert result['fork_of_id'] == master_repo.repo_id + result = response.json["result"]["repository"] + assert result["fork_of"] == master_repo.repo_name + assert result["fork_of_id"] == master_repo.repo_id def test_api_update_repo_fork_of_not_found(self, backend): - master_repo_name = 'fake-parent-repo' + master_repo_name = "fake-parent-repo" repo = backend.create_repo() - updates = { - 'fork_of': master_repo_name - } - id_, params = build_data( - self.apikey, 'update_repo', repoid=repo.repo_name, **updates) + updates = {"fork_of": master_repo_name} + id_, params = build_data(self.apikey, "update_repo", repoid=repo.repo_name, **updates) response = api_call(self.app, params) - expected = { - 'repo_fork_of': 'Fork with id `{}` does not exists'.format( - master_repo_name)} + expected = {"repo_fork_of": "Fork with id `{}` does not exists".format(master_repo_name)} assert_error(id_, expected, given=response.body) def test_api_update_repo_with_repo_group_not_existing(self): - repo_name = 'admin_owned' - fake_repo_group = 'test_group_for_update' + repo_name = "admin_owned" + fake_repo_group = "test_group_for_update" fixture.create_repo(repo_name) - updates = {'repo_name': '{}/{}'.format(fake_repo_group, repo_name)} - id_, params = build_data( - self.apikey, 'update_repo', repoid=repo_name, **updates) + updates = {"repo_name": "{}/{}".format(fake_repo_group, repo_name)} + id_, params = build_data(self.apikey, "update_repo", repoid=repo_name, **updates) response = api_call(self.app, params) try: - expected = { - 'repo_group': 'Repository group `{}` does not exist'.format(fake_repo_group) - } + expected = {"repo_group": "Repository group `{}` does not exist".format(fake_repo_group)} assert_error(id_, expected, given=response.body) finally: fixture.destroy_repo(repo_name) def test_api_update_repo_regular_user_not_allowed(self): - repo_name = 'admin_owned' + repo_name = "admin_owned" fixture.create_repo(repo_name) - updates = {'active': False} - id_, params = build_data( - self.apikey_regular, 'update_repo', repoid=repo_name, **updates) + updates = {"active": False} + id_, params = build_data(self.apikey_regular, "update_repo", repoid=repo_name, **updates) response = api_call(self.app, params) try: - expected = 'repository `%s` does not exist' % (repo_name,) + expected = "repository `%s` does not exist" % (repo_name,) assert_error(id_, expected, given=response.body) finally: fixture.destroy_repo(repo_name) - @mock.patch.object(RepoModel, 'update', crash) + @mock.patch.object(RepoModel, "update", crash) def test_api_update_repo_exception_occurred(self, backend): repo_name = UPDATE_REPO_NAME fixture.create_repo(repo_name, repo_type=backend.alias) id_, params = build_data( - self.apikey, 'update_repo', repoid=repo_name, - owner=TEST_USER_ADMIN_LOGIN,) + self.apikey, + "update_repo", + repoid=repo_name, + owner=TEST_USER_ADMIN_LOGIN, + ) response = api_call(self.app, params) try: - expected = 'failed to update repo `%s`' % (repo_name,) + expected = "failed to update repo `%s`" % (repo_name,) assert_error(id_, expected, given=response.body) finally: fixture.destroy_repo(repo_name) diff --git a/rhodecode/api/tests/test_update_repo_group.py b/rhodecode/api/tests/test_update_repo_group.py index 89704a90..107400ad 100644 --- a/rhodecode/api/tests/test_update_repo_group.py +++ b/rhodecode/api/tests/test_update_repo_group.py @@ -22,15 +22,13 @@ import pytest from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.user import UserModel -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok @pytest.mark.usefixtures("testuser_api", "app") class TestApiUpdateRepoGroup(object): - def test_update_group_name(self, user_util): - new_group_name = 'new-group' + new_group_name = "new-group" initial_name = self._update(user_util, group_name=new_group_name) assert RepoGroupModel()._get_repo_group(initial_name) is None new_group = RepoGroupModel()._get_repo_group(new_group_name) @@ -38,11 +36,10 @@ class TestApiUpdateRepoGroup(object): assert new_group.full_path == new_group_name def test_update_group_name_change_parent(self, user_util): - parent_group = user_util.create_repo_group() parent_group_name = parent_group.name - expected_group_name = '{}/{}'.format(parent_group_name, 'new-group') + expected_group_name = "{}/{}".format(parent_group_name, "new-group") initial_name = self._update(user_util, group_name=expected_group_name) repo_group = RepoGroupModel()._get_repo_group(expected_group_name) @@ -52,8 +49,7 @@ class TestApiUpdateRepoGroup(object): assert repo_group.full_path == expected_group_name assert RepoGroupModel()._get_repo_group(initial_name) is None - new_path = os.path.join( - RepoGroupModel().repos_path, *repo_group.full_path_splitted) + new_path = os.path.join(RepoGroupModel().repos_path, *repo_group.full_path_splitted) assert os.path.exists(new_path) def test_update_enable_locking(self, user_util): @@ -62,7 +58,7 @@ class TestApiUpdateRepoGroup(object): assert repo_group.enable_locking is True def test_update_description(self, user_util): - description = 'New description' + description = "New description" initial_name = self._update(user_util, description=description) repo_group = RepoGroupModel()._get_repo_group(initial_name) assert repo_group.group_description == description @@ -80,13 +76,12 @@ class TestApiUpdateRepoGroup(object): repo_group_name_2 = group_2.group_name id_, params = build_data( - self.apikey, 'update_repo_group', repogroupid=repo_group_name_1, - group_name=repo_group_name_2) + self.apikey, "update_repo_group", repogroupid=repo_group_name_1, group_name=repo_group_name_2 + ) response = api_call(self.app, params) expected = { - 'unique_repo_group_name': - 'Repository group with name `{}` already exists'.format( - repo_group_name_2)} + "unique_repo_group_name": "Repository group with name `{}` already exists".format(repo_group_name_2) + } assert_error(id_, expected, given=response.body) def test_api_update_repo_group_by_regular_user_no_permission(self, user_util): @@ -94,55 +89,45 @@ class TestApiUpdateRepoGroup(object): temp_user_api_key = temp_user.api_key parent_group = user_util.create_repo_group() repo_group_name = parent_group.group_name - id_, params = build_data( - temp_user_api_key, 'update_repo_group', repogroupid=repo_group_name) + id_, params = build_data(temp_user_api_key, "update_repo_group", repogroupid=repo_group_name) response = api_call(self.app, params) - expected = 'repository group `%s` does not exist' % (repo_group_name,) + expected = "repository group `%s` does not exist" % (repo_group_name,) assert_error(id_, expected, given=response.body) - def test_api_update_repo_group_regular_user_no_root_write_permissions( - self, user_util): + def test_api_update_repo_group_regular_user_no_root_write_permissions(self, user_util): temp_user = user_util.create_user() temp_user_api_key = temp_user.api_key parent_group = user_util.create_repo_group(owner=temp_user.username) repo_group_name = parent_group.group_name id_, params = build_data( - temp_user_api_key, 'update_repo_group', repogroupid=repo_group_name, - group_name='at-root-level') + temp_user_api_key, "update_repo_group", repogroupid=repo_group_name, group_name="at-root-level" + ) response = api_call(self.app, params) - expected = { - 'repo_group': 'You do not have the permission to store ' - 'repository groups in the root location.'} + expected = {"repo_group": "You do not have the permission to store repository groups in the root location."} assert_error(id_, expected, given=response.body) def _update(self, user_util, **kwargs): repo_group = user_util.create_repo_group() initial_name = repo_group.name user = UserModel().get_by_username(self.TEST_USER_LOGIN) - user_util.grant_user_permission_to_repo_group( - repo_group, user, 'group.admin') + user_util.grant_user_permission_to_repo_group(repo_group, user, "group.admin") - id_, params = build_data( - self.apikey, 'update_repo_group', repogroupid=initial_name, - **kwargs) + id_, params = build_data(self.apikey, "update_repo_group", repogroupid=initial_name, **kwargs) response = api_call(self.app, params) repo_group = RepoGroupModel.cls.get(repo_group.group_id) expected = { - 'msg': 'updated repository group ID:{} {}'.format( - repo_group.group_id, repo_group.group_name), - 'repo_group': { - 'repositories': [], - 'group_name': repo_group.group_name, - 'group_description': repo_group.group_description, - 'owner': repo_group.user.username, - 'group_id': repo_group.group_id, - 'parent_group': ( - repo_group.parent_group.name - if repo_group.parent_group else None) - } + "msg": "updated repository group ID:{} {}".format(repo_group.group_id, repo_group.group_name), + "repo_group": { + "repositories": [], + "group_name": repo_group.group_name, + "group_description": repo_group.group_description, + "owner": repo_group.user.username, + "group_id": repo_group.group_id, + "parent_group": (repo_group.parent_group.name if repo_group.parent_group else None), + }, } assert_ok(id_, expected, given=response.body) return initial_name diff --git a/rhodecode/api/tests/test_update_user.py b/rhodecode/api/tests/test_update_user.py index c3420970..a733a5b9 100644 --- a/rhodecode/api/tests/test_update_user.py +++ b/rhodecode/api/tests/test_update_user.py @@ -22,41 +22,39 @@ import pytest from rhodecode.model.db import User from rhodecode.model.user import UserModel from rhodecode.tests import TEST_USER_ADMIN_LOGIN -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_ok, assert_error, crash, jsonify) +from rhodecode.api.tests.utils import build_data, api_call, assert_ok, assert_error, crash, jsonify @pytest.mark.usefixtures("testuser_api", "app") class TestUpdateUser(object): - @pytest.mark.parametrize("name, expected", [ - ('firstname', 'new_username'), - ('lastname', 'new_username'), - ('email', 'new_username'), - ('admin', True), - ('admin', False), - ('extern_type', 'ldap'), - ('extern_type', None), - ('extern_name', 'test'), - ('extern_name', None), - ('active', False), - ('active', True), - ('password', 'newpass'), - ('description', 'CTO 4 Life') - ]) + @pytest.mark.parametrize( + "name, expected", + [ + ("firstname", "new_username"), + ("lastname", "new_username"), + ("email", "new_username"), + ("admin", True), + ("admin", False), + ("extern_type", "ldap"), + ("extern_type", None), + ("extern_name", "test"), + ("extern_name", None), + ("active", False), + ("active", True), + ("password", "newpass"), + ("description", "CTO 4 Life"), + ], + ) def test_api_update_user(self, name, expected, user_util): usr = user_util.create_user() - kw = {name: expected, 'userid': usr.user_id} - id_, params = build_data(self.apikey, 'update_user', **kw) + kw = {name: expected, "userid": usr.user_id} + id_, params = build_data(self.apikey, "update_user", **kw) response = api_call(self.app, params) ret = { - 'msg': 'updated user ID:%s %s' % (usr.user_id, usr.username), - 'user': jsonify( - UserModel() - .get_by_username(usr.username) - .get_api_data(include_secrets=True) - ) + "msg": "updated user ID:%s %s" % (usr.user_id, usr.username), + "user": jsonify(UserModel().get_by_username(usr.username).get_api_data(include_secrets=True)), } expected = ret @@ -65,55 +63,41 @@ class TestUpdateUser(object): def test_api_update_user_no_changed_params(self): usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) ret = jsonify(usr.get_api_data(include_secrets=True)) - id_, params = build_data( - self.apikey, 'update_user', userid=TEST_USER_ADMIN_LOGIN) + id_, params = build_data(self.apikey, "update_user", userid=TEST_USER_ADMIN_LOGIN) response = api_call(self.app, params) - ret = { - 'msg': 'updated user ID:%s %s' % ( - usr.user_id, TEST_USER_ADMIN_LOGIN), - 'user': ret - } + ret = {"msg": "updated user ID:%s %s" % (usr.user_id, TEST_USER_ADMIN_LOGIN), "user": ret} expected = ret - expected['user']['last_activity'] = response.json['result']['user'][ - 'last_activity'] + expected["user"]["last_activity"] = response.json["result"]["user"]["last_activity"] assert_ok(id_, expected, given=response.body) def test_api_update_user_by_user_id(self): usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) ret = jsonify(usr.get_api_data(include_secrets=True)) - id_, params = build_data( - self.apikey, 'update_user', userid=usr.user_id) + id_, params = build_data(self.apikey, "update_user", userid=usr.user_id) response = api_call(self.app, params) - ret = { - 'msg': 'updated user ID:%s %s' % ( - usr.user_id, TEST_USER_ADMIN_LOGIN), - 'user': ret - } + ret = {"msg": "updated user ID:%s %s" % (usr.user_id, TEST_USER_ADMIN_LOGIN), "user": ret} expected = ret - expected['user']['last_activity'] = response.json['result']['user'][ - 'last_activity'] + expected["user"]["last_activity"] = response.json["result"]["user"]["last_activity"] assert_ok(id_, expected, given=response.body) def test_api_update_user_default_user(self): usr = User.get_default_user() - id_, params = build_data( - self.apikey, 'update_user', userid=usr.user_id) + id_, params = build_data(self.apikey, "update_user", userid=usr.user_id) response = api_call(self.app, params) - expected = 'editing default user is forbidden' + expected = "editing default user is forbidden" assert_error(id_, expected, given=response.body) - @mock.patch.object(UserModel, 'update_user', crash) + @mock.patch.object(UserModel, "update_user", crash) def test_api_update_user_when_exception_happens(self): usr = UserModel().get_by_username(TEST_USER_ADMIN_LOGIN) ret = jsonify(usr.get_api_data(include_secrets=True)) - id_, params = build_data( - self.apikey, 'update_user', userid=usr.user_id) + id_, params = build_data(self.apikey, "update_user", userid=usr.user_id) response = api_call(self.app, params) - ret = 'failed to update user `%s`' % (usr.user_id,) + ret = "failed to update user `%s`" % (usr.user_id,) expected = ret assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_update_user_group.py b/rhodecode/api/tests/test_update_user_group.py index 1cbe92e2..0f497f67 100644 --- a/rhodecode/api/tests/test_update_user_group.py +++ b/rhodecode/api/tests/test_update_user_group.py @@ -22,59 +22,60 @@ import pytest from rhodecode.model.user import UserModel from rhodecode.model.user_group import UserGroupModel from rhodecode.tests import TEST_USER_ADMIN_EMAIL -from rhodecode.api.tests.utils import ( - build_data, api_call, assert_error, assert_ok, crash, jsonify) +from rhodecode.api.tests.utils import build_data, api_call, assert_error, assert_ok, crash, jsonify @pytest.mark.usefixtures("testuser_api", "app") class TestUpdateUserGroup(object): - @pytest.mark.parametrize("changing_attr, updates", [ - ('group_name', {'group_name': 'new_group_name'}), - ('group_name', {'group_name': 'test_group_for_update'}), - # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}), - ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}), - ('active', {'active': False}), - ('active', {'active': True}), - ('sync', {'sync': False}), - ('sync', {'sync': True}) - ]) + @pytest.mark.parametrize( + "changing_attr, updates", + [ + ("group_name", {"group_name": "new_group_name"}), + ("group_name", {"group_name": "test_group_for_update"}), + # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}), + ("owner_email", {"owner_email": TEST_USER_ADMIN_EMAIL}), + ("active", {"active": False}), + ("active", {"active": True}), + ("sync", {"sync": False}), + ("sync", {"sync": True}), + ], + ) def test_api_update_user_group(self, changing_attr, updates, user_util): user_group = user_util.create_user_group() group_name = user_group.users_group_name expected_api_data = user_group.get_api_data() expected_api_data.update(updates) - id_, params = build_data( - self.apikey, 'update_user_group', usergroupid=group_name, - **updates) + id_, params = build_data(self.apikey, "update_user_group", usergroupid=group_name, **updates) response = api_call(self.app, params) # special case for sync - if changing_attr == 'sync' and updates['sync'] is False: - expected_api_data['sync'] = None - elif changing_attr == 'sync' and updates['sync'] is True: - expected_api_data['sync'] = 'manual_api' + if changing_attr == "sync" and updates["sync"] is False: + expected_api_data["sync"] = None + elif changing_attr == "sync" and updates["sync"] is True: + expected_api_data["sync"] = "manual_api" expected = { - 'msg': 'updated user group ID:%s %s' % ( - user_group.users_group_id, user_group.users_group_name), - 'user_group': jsonify(expected_api_data) + "msg": "updated user group ID:%s %s" % (user_group.users_group_id, user_group.users_group_name), + "user_group": jsonify(expected_api_data), } assert_ok(id_, expected, given=response.body) - @pytest.mark.parametrize("changing_attr, updates", [ - # TODO: mikhail: decide if we need to test against the commented params - # ('group_name', {'group_name': 'new_group_name'}), - # ('group_name', {'group_name': 'test_group_for_update'}), - # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}), - ('owner_email', {'owner_email': TEST_USER_ADMIN_EMAIL}), - ('active', {'active': False}), - ('active', {'active': True}), - ('sync', {'sync': False}), - ('sync', {'sync': True}) - ]) - def test_api_update_user_group_regular_user( - self, changing_attr, updates, user_util): + @pytest.mark.parametrize( + "changing_attr, updates", + [ + # TODO: mikhail: decide if we need to test against the commented params + # ('group_name', {'group_name': 'new_group_name'}), + # ('group_name', {'group_name': 'test_group_for_update'}), + # ('owner', {'owner': TEST_USER_REGULAR_LOGIN}), + ("owner_email", {"owner_email": TEST_USER_ADMIN_EMAIL}), + ("active", {"active": False}), + ("active", {"active": True}), + ("sync", {"sync": False}), + ("sync", {"sync": True}), + ], + ) + def test_api_update_user_group_regular_user(self, changing_attr, updates, user_util): user_group = user_util.create_user_group() group_name = user_group.users_group_name expected_api_data = user_group.get_api_data() @@ -83,41 +84,35 @@ class TestUpdateUserGroup(object): # grant permission to this user user = UserModel().get_by_username(self.TEST_USER_LOGIN) - user_util.grant_user_permission_to_user_group( - user_group, user, 'usergroup.admin') - id_, params = build_data( - self.apikey_regular, 'update_user_group', - usergroupid=group_name, **updates) + user_util.grant_user_permission_to_user_group(user_group, user, "usergroup.admin") + id_, params = build_data(self.apikey_regular, "update_user_group", usergroupid=group_name, **updates) response = api_call(self.app, params) # special case for sync - if changing_attr == 'sync' and updates['sync'] is False: - expected_api_data['sync'] = None - elif changing_attr == 'sync' and updates['sync'] is True: - expected_api_data['sync'] = 'manual_api' + if changing_attr == "sync" and updates["sync"] is False: + expected_api_data["sync"] = None + elif changing_attr == "sync" and updates["sync"] is True: + expected_api_data["sync"] = "manual_api" expected = { - 'msg': 'updated user group ID:%s %s' % ( - user_group.users_group_id, user_group.users_group_name), - 'user_group': jsonify(expected_api_data) + "msg": "updated user group ID:%s %s" % (user_group.users_group_id, user_group.users_group_name), + "user_group": jsonify(expected_api_data), } assert_ok(id_, expected, given=response.body) def test_api_update_user_group_regular_user_no_permission(self, user_util): user_group = user_util.create_user_group() group_name = user_group.users_group_name - id_, params = build_data( - self.apikey_regular, 'update_user_group', usergroupid=group_name) + id_, params = build_data(self.apikey_regular, "update_user_group", usergroupid=group_name) response = api_call(self.app, params) - expected = 'user group `%s` does not exist' % (group_name) + expected = "user group `%s` does not exist" % (group_name) assert_error(id_, expected, given=response.body) - @mock.patch.object(UserGroupModel, 'update', crash) + @mock.patch.object(UserGroupModel, "update", crash) def test_api_update_user_group_exception_occurred(self, user_util): user_group = user_util.create_user_group() group_name = user_group.users_group_name - id_, params = build_data( - self.apikey, 'update_user_group', usergroupid=group_name) + id_, params = build_data(self.apikey, "update_user_group", usergroupid=group_name) response = api_call(self.app, params) - expected = 'failed to update user group `%s`' % (group_name,) + expected = "failed to update user group `%s`" % (group_name,) assert_error(id_, expected, given=response.body) diff --git a/rhodecode/api/tests/test_utils.py b/rhodecode/api/tests/test_utils.py index 9429ce67..0a8abeff 100644 --- a/rhodecode/api/tests/test_utils.py +++ b/rhodecode/api/tests/test_utils.py @@ -26,169 +26,148 @@ from rhodecode.lib.vcs.exceptions import RepositoryError class TestGetCommitOrError(object): - def setup_method(self): - self.commit_hash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10' + self.commit_hash = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10" - @pytest.mark.parametrize("ref", ['ref', '12345', 'a:b:c:d', 'branch:name']) + @pytest.mark.parametrize("ref", ["ref", "12345", "a:b:c:d", "branch:name"]) def test_ref_cannot_be_parsed(self, ref): repo = Mock() with pytest.raises(JSONRPCError) as excinfo: utils.get_commit_or_error(ref, repo) expected_message = ( - 'Ref `{ref}` given in a wrong format. Please check the API' - ' documentation for more details'.format(ref=ref) + "Ref `{ref}` given in a wrong format. Please check the API documentation for more details".format(ref=ref) ) assert excinfo.value.message == expected_message def test_success_with_hash_specified(self): repo = Mock() - ref_type = 'branch' - ref = '{}:master:{}'.format(ref_type, self.commit_hash) + ref_type = "branch" + ref = "{}:master:{}".format(ref_type, self.commit_hash) - with patch('rhodecode.api.utils.get_commit_from_ref_name') as get_commit: + with patch("rhodecode.api.utils.get_commit_from_ref_name") as get_commit: result = utils.get_commit_or_error(ref, repo) - get_commit.assert_called_once_with( - repo, self.commit_hash) + get_commit.assert_called_once_with(repo, self.commit_hash) assert result == get_commit() def test_raises_an_error_when_commit_not_found(self): repo = Mock() - ref = 'branch:master:{}'.format(self.commit_hash) + ref = "branch:master:{}".format(self.commit_hash) - with patch('rhodecode.api.utils.get_commit_from_ref_name') as get_commit: - get_commit.side_effect = RepositoryError('Commit not found') + with patch("rhodecode.api.utils.get_commit_from_ref_name") as get_commit: + get_commit.side_effect = RepositoryError("Commit not found") with pytest.raises(JSONRPCError) as excinfo: utils.get_commit_or_error(ref, repo) - expected_message = 'Ref `{}` does not exist'.format(ref) + expected_message = "Ref `{}` does not exist".format(ref) assert excinfo.value.message == expected_message class TestResolveRefOrError(object): - def setup_method(self): - self.commit_hash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10' + self.commit_hash = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10" def test_success_with_no_hash_specified(self): repo = Mock() - ref_type = 'branch' - ref_name = 'master' - ref = '{}:{}'.format(ref_type, ref_name) + ref_type = "branch" + ref_name = "master" + ref = "{}:{}".format(ref_type, ref_name) - with patch('rhodecode.api.utils._get_ref_hash') \ - as _get_ref_hash: + with patch("rhodecode.api.utils._get_ref_hash") as _get_ref_hash: _get_ref_hash.return_value = self.commit_hash result = utils.resolve_ref_or_error(ref, repo) _get_ref_hash.assert_called_once_with(repo, ref_type, ref_name) - assert result == '{}:{}'.format(ref, self.commit_hash) + assert result == "{}:{}".format(ref, self.commit_hash) def test_non_supported_refs(self): repo = Mock() - ref = 'bookmark:ref' + ref = "bookmark:ref" with pytest.raises(JSONRPCError) as excinfo: utils.resolve_ref_or_error(ref, repo) - expected_message = ( - 'The specified value:bookmark:`ref` does not exist, or is not allowed.') + expected_message = "The specified value:bookmark:`ref` does not exist, or is not allowed." assert excinfo.value.message == expected_message def test_branch_is_not_found(self): repo = Mock() - ref = 'branch:non-existing-one' - with patch('rhodecode.api.utils._get_ref_hash')\ - as _get_ref_hash: + ref = "branch:non-existing-one" + with patch("rhodecode.api.utils._get_ref_hash") as _get_ref_hash: _get_ref_hash.side_effect = KeyError() with pytest.raises(JSONRPCError) as excinfo: utils.resolve_ref_or_error(ref, repo) - expected_message = ( - 'The specified value:branch:`non-existing-one` does not exist, or is not allowed.') + expected_message = "The specified value:branch:`non-existing-one` does not exist, or is not allowed." assert excinfo.value.message == expected_message def test_bookmark_is_not_found(self): repo = Mock() - ref = 'bookmark:non-existing-one' - with patch('rhodecode.api.utils._get_ref_hash')\ - as _get_ref_hash: + ref = "bookmark:non-existing-one" + with patch("rhodecode.api.utils._get_ref_hash") as _get_ref_hash: _get_ref_hash.side_effect = KeyError() with pytest.raises(JSONRPCError) as excinfo: utils.resolve_ref_or_error(ref, repo) - expected_message = ( - 'The specified value:bookmark:`non-existing-one` does not exist, or is not allowed.') + expected_message = "The specified value:bookmark:`non-existing-one` does not exist, or is not allowed." assert excinfo.value.message == expected_message - @pytest.mark.parametrize("ref", ['ref', '12345', 'a:b:c:d']) + @pytest.mark.parametrize("ref", ["ref", "12345", "a:b:c:d"]) def test_ref_cannot_be_parsed(self, ref): repo = Mock() with pytest.raises(JSONRPCError) as excinfo: utils.resolve_ref_or_error(ref, repo) expected_message = ( - 'Ref `{ref}` given in a wrong format. Please check the API' - ' documentation for more details'.format(ref=ref) + "Ref `{ref}` given in a wrong format. Please check the API documentation for more details".format(ref=ref) ) assert excinfo.value.message == expected_message class TestGetRefHash(object): - def setup_method(self): - self.commit_hash = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10' - self.bookmark_name = 'test-bookmark' + self.commit_hash = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa10" + self.bookmark_name = "test-bookmark" - @pytest.mark.parametrize("alias, branch_name", [ - ("git", "master"), - ("hg", "default") - ]) + @pytest.mark.parametrize("alias, branch_name", [("git", "master"), ("hg", "default")]) def test_returns_hash_by_branch_name(self, alias, branch_name): - with patch('rhodecode.model.db.Repository') as repo: + with patch("rhodecode.model.db.Repository") as repo: repo.scm_instance().alias = alias repo.scm_instance().branches = {branch_name: self.commit_hash} - result_hash = utils._get_ref_hash(repo, 'branch', branch_name) + result_hash = utils._get_ref_hash(repo, "branch", branch_name) assert result_hash == self.commit_hash - @pytest.mark.parametrize("alias, branch_name", [ - ("git", "master"), - ("hg", "default") - ]) + @pytest.mark.parametrize("alias, branch_name", [("git", "master"), ("hg", "default")]) def test_raises_error_when_branch_is_not_found(self, alias, branch_name): - with patch('rhodecode.model.db.Repository') as repo: + with patch("rhodecode.model.db.Repository") as repo: repo.scm_instance().alias = alias repo.scm_instance().branches = {} with pytest.raises(KeyError): - utils._get_ref_hash(repo, 'branch', branch_name) + utils._get_ref_hash(repo, "branch", branch_name) def test_returns_hash_when_bookmark_is_specified_for_hg(self): - with patch('rhodecode.model.db.Repository') as repo: - repo.scm_instance().alias = 'hg' - repo.scm_instance().bookmarks = { - self.bookmark_name: self.commit_hash} - result_hash = utils._get_ref_hash( - repo, 'bookmark', self.bookmark_name) + with patch("rhodecode.model.db.Repository") as repo: + repo.scm_instance().alias = "hg" + repo.scm_instance().bookmarks = {self.bookmark_name: self.commit_hash} + result_hash = utils._get_ref_hash(repo, "bookmark", self.bookmark_name) assert result_hash == self.commit_hash def test_raises_error_when_bookmark_is_not_found_in_hg_repo(self): - with patch('rhodecode.model.db.Repository') as repo: - repo.scm_instance().alias = 'hg' + with patch("rhodecode.model.db.Repository") as repo: + repo.scm_instance().alias = "hg" repo.scm_instance().bookmarks = {} with pytest.raises(KeyError): - utils._get_ref_hash(repo, 'bookmark', self.bookmark_name) + utils._get_ref_hash(repo, "bookmark", self.bookmark_name) def test_raises_error_when_bookmark_is_specified_for_git(self): - with patch('rhodecode.model.db.Repository') as repo: - repo.scm_instance().alias = 'git' - repo.scm_instance().bookmarks = { - self.bookmark_name: self.commit_hash} + with patch("rhodecode.model.db.Repository") as repo: + repo.scm_instance().alias = "git" + repo.scm_instance().bookmarks = {self.bookmark_name: self.commit_hash} with pytest.raises(ValueError): - utils._get_ref_hash(repo, 'bookmark', self.bookmark_name) + utils._get_ref_hash(repo, "bookmark", self.bookmark_name) class TestUserByNameOrError(object): def test_user_found_by_id(self): fake_user = Mock(id=123) - patcher = patch('rhodecode.model.user.UserModel.get_user') + patcher = patch("rhodecode.model.user.UserModel.get_user") with patcher as get_user: get_user.return_value = fake_user - patcher = patch('rhodecode.model.user.UserModel.get_by_username') + patcher = patch("rhodecode.model.user.UserModel.get_by_username") with patcher as get_by_username: result = utils.get_user_or_error(123) assert result == fake_user @@ -196,94 +175,91 @@ class TestUserByNameOrError(object): def test_user_not_found_by_id_as_str(self): fake_user = Mock(id=123) - patcher = patch('rhodecode.model.user.UserModel.get_user') + patcher = patch("rhodecode.model.user.UserModel.get_user") with patcher as get_user: get_user.return_value = fake_user - patcher = patch('rhodecode.model.user.UserModel.get_by_username') + patcher = patch("rhodecode.model.user.UserModel.get_by_username") with patcher as get_by_username: get_by_username.return_value = None with pytest.raises(JSONRPCError): - utils.get_user_or_error('123') + utils.get_user_or_error("123") def test_user_found_by_name(self): fake_user = Mock(id=123) - patcher = patch('rhodecode.model.user.UserModel.get_user') + patcher = patch("rhodecode.model.user.UserModel.get_user") with patcher as get_user: get_user.return_value = None - patcher = patch('rhodecode.model.user.UserModel.get_by_username') + patcher = patch("rhodecode.model.user.UserModel.get_by_username") with patcher as get_by_username: get_by_username.return_value = fake_user - result = utils.get_user_or_error('test') + result = utils.get_user_or_error("test") assert result == fake_user def test_user_not_found_by_id(self): - patcher = patch('rhodecode.model.user.UserModel.get_user') + patcher = patch("rhodecode.model.user.UserModel.get_user") with patcher as get_user: get_user.return_value = None - patcher = patch('rhodecode.model.user.UserModel.get_by_username') + patcher = patch("rhodecode.model.user.UserModel.get_by_username") with patcher as get_by_username: get_by_username.return_value = None with pytest.raises(JSONRPCError) as excinfo: utils.get_user_or_error(123) - expected_message = 'user `123` does not exist' + expected_message = "user `123` does not exist" assert excinfo.value.message == expected_message def test_user_not_found_by_name(self): - patcher = patch('rhodecode.model.user.UserModel.get_by_username') + patcher = patch("rhodecode.model.user.UserModel.get_by_username") with patcher as get_by_username: get_by_username.return_value = None with pytest.raises(JSONRPCError) as excinfo: - utils.get_user_or_error('test') + utils.get_user_or_error("test") - expected_message = 'user `test` does not exist' + expected_message = "user `test` does not exist" assert excinfo.value.message == expected_message class TestGetCommitDict(object): - @pytest.mark.parametrize('filename, expected', [ - (b'sp\xc3\xa4cial', u'sp\xe4cial'), - (b'sp\xa4cial', u'sp\ufffdcial'), - ]) + @pytest.mark.parametrize( + "filename, expected", + [ + (b"sp\xc3\xa4cial", "sp\xe4cial"), + (b"sp\xa4cial", "sp\ufffdcial"), + ], + ) def test_decodes_filenames_to_unicode(self, filename, expected): - result = utils._get_commit_dict(filename=filename, op='A') - assert result['filename'] == expected + result = utils._get_commit_dict(filename=filename, op="A") + assert result["filename"] == expected class TestRepoAccess(object): def setup_method(self, method): - - self.admin_perm_patch = patch( - 'rhodecode.api.utils.HasPermissionAnyApi') - self.repo_perm_patch = patch( - 'rhodecode.api.utils.HasRepoPermissionAnyApi') + self.admin_perm_patch = patch("rhodecode.api.utils.HasPermissionAnyApi") + self.repo_perm_patch = patch("rhodecode.api.utils.HasRepoPermissionAnyApi") def test_has_superadmin_permission_checks_for_admin(self): admin_mock = Mock() with self.admin_perm_patch as amock: amock.return_value = admin_mock - assert utils.has_superadmin_permission('fake_user') - amock.assert_called_once_with('hg.admin') + assert utils.has_superadmin_permission("fake_user") + amock.assert_called_once_with("hg.admin") - admin_mock.assert_called_once_with(user='fake_user') + admin_mock.assert_called_once_with(user="fake_user") def test_has_repo_permissions_checks_for_repo_access(self): repo_mock = Mock() fake_repo = Mock() with self.repo_perm_patch as rmock: rmock.return_value = repo_mock - assert utils.validate_repo_permissions( - 'fake_user', 'fake_repo_id', fake_repo, - ['perm1', 'perm2']) - rmock.assert_called_once_with(*['perm1', 'perm2']) + assert utils.validate_repo_permissions("fake_user", "fake_repo_id", fake_repo, ["perm1", "perm2"]) + rmock.assert_called_once_with(*["perm1", "perm2"]) - repo_mock.assert_called_once_with( - user='fake_user', repo_name=fake_repo.repo_name) + repo_mock.assert_called_once_with(user="fake_user", repo_name=fake_repo.repo_name) def test_has_repo_permissions_raises_not_found(self): repo_mock = Mock(return_value=False) @@ -291,6 +267,5 @@ class TestRepoAccess(object): with self.repo_perm_patch as rmock: rmock.return_value = repo_mock with pytest.raises(JSONRPCError) as excinfo: - utils.validate_repo_permissions( - 'fake_user', 'fake_repo_id', fake_repo, 'perms') - assert 'fake_repo_id' in excinfo + utils.validate_repo_permissions("fake_user", "fake_repo_id", fake_repo, "perms") + assert "fake_repo_id" in excinfo diff --git a/rhodecode/api/tests/utils.py b/rhodecode/api/tests/utils.py index 30565c19..930f898d 100644 --- a/rhodecode/api/tests/utils.py +++ b/rhodecode/api/tests/utils.py @@ -28,43 +28,31 @@ def jsonify(obj): return json.loads(json.dumps(obj)) -API_URL = '/_admin/api' +API_URL = "/_admin/api" def assert_call_ok(id_, given): - expected = jsonify({ - 'id': id_, - 'error': None, - 'result': None - }) + expected = jsonify({"id": id_, "error": None, "result": None}) given = json.loads(given) - assert expected['id'] == given['id'] - assert expected['error'] == given['error'] - return given['result'] + assert expected["id"] == given["id"] + assert expected["error"] == given["error"] + return given["result"] def assert_ok(id_, expected, given): given = json.loads(given) - if given.get('error'): - err = given['error'] + if given.get("error"): + err = given["error"] pytest.fail(f"Unexpected ERROR in expected success response: `{err}`") - expected = jsonify({ - 'id': id_, - 'error': None, - 'result': expected - }) + expected = jsonify({"id": id_, "error": None, "result": expected}) assert expected == given def assert_error(id_, expected, given): - expected = jsonify({ - 'id': id_, - 'error': expected, - 'result': None - }) + expected = jsonify({"id": id_, "error": expected, "result": None}) given = json.loads(given) assert expected == given @@ -74,27 +62,26 @@ def build_data(apikey, method, **kw): Builds API data with given random ID """ random_id = random.randrange(1, 9999) - return random_id, json.dumps({ - "id": random_id, - "api_key": apikey, - "method": method, - "args": kw - }) + return random_id, json.dumps({"id": random_id, "api_key": apikey, "method": method, "args": kw}) def api_call(app, params, status=None, assert_no_error=False): response = app.post( - API_URL, content_type='application/json', params=params, status=status, - headers=[('Content-Type', 'application/json')]) + API_URL, + content_type="application/json", + params=params, + status=status, + headers=[("Content-Type", "application/json")], + ) if assert_no_error: - err_resp = response.json.get('error') + err_resp = response.json.get("error") if err_resp: - raise AssertionError(f'ERROR in response: {err_resp}') + raise AssertionError(f"ERROR in response: {err_resp}") return response def crash(*args, **kwargs): - raise Exception('Total Crash !') + raise Exception("Total Crash !") def expected_permissions(object_with_permissions): @@ -108,19 +95,19 @@ def expected_permissions(object_with_permissions): permissions = [] for _user in object_with_permissions.permissions(): user_data = { - 'name': _user.username, - 'permission': _user.permission, - 'origin': get_origin(_user), - 'type': "user", + "name": _user.username, + "permission": _user.permission, + "origin": get_origin(_user), + "type": "user", } permissions.append(user_data) for _user_group in object_with_permissions.permission_user_groups(): user_group_data = { - 'name': _user_group.users_group_name, - 'permission': _user_group.permission, - 'origin': get_origin(_user_group), - 'type': "user_group", + "name": _user_group.users_group_name, + "permission": _user_group.permission, + "origin": get_origin(_user_group), + "type": "user_group", } permissions.append(user_group_data) return permissions diff --git a/rhodecode/api/utils.py b/rhodecode/api/utils.py index 82a204d5..afd7532e 100644 --- a/rhodecode/api/utils.py +++ b/rhodecode/api/utils.py @@ -24,8 +24,7 @@ import collections import logging from rhodecode.api.exc import JSONRPCError -from rhodecode.lib.auth import ( - HasPermissionAnyApi, HasRepoPermissionAnyApi, HasRepoGroupPermissionAnyApi) +from rhodecode.lib.auth import HasPermissionAnyApi, HasRepoPermissionAnyApi, HasRepoGroupPermissionAnyApi from rhodecode.lib.str_utils import safe_str from rhodecode.lib.vcs.exceptions import RepositoryError from rhodecode.lib.view_utils import get_commit_from_ref_name @@ -50,7 +49,7 @@ class OAttr(object): self.attr_name = attr_name def __repr__(self): - return '' % self.attr_name + return "" % self.attr_name def __call__(self): return self @@ -73,7 +72,7 @@ class Optional(object): self.type_ = type_ def __repr__(self): - return '' % self.type_.__repr__() + return "" % self.type_.__repr__() def __call__(self): return self.getval() @@ -108,11 +107,12 @@ class Optional(object): return val -def parse_args(cli_args, key_prefix=''): - from rhodecode.lib.utils2 import (escape_split) +def parse_args(cli_args, key_prefix=""): + from rhodecode.lib.utils2 import escape_split + kwargs = collections.defaultdict(dict) - for el in escape_split(cli_args, ','): - kv = escape_split(el, '=', 1) + for el in escape_split(cli_args, ","): + kv = escape_split(el, "=", 1) if len(kv) == 2: k, v = kv kwargs[key_prefix + k] = v @@ -125,15 +125,15 @@ def get_origin(obj): :param obj: """ - origin = 'permission' + origin = "permission" - if getattr(obj, 'owner_row', '') and getattr(obj, 'admin_row', ''): + if getattr(obj, "owner_row", "") and getattr(obj, "admin_row", ""): # admin and owner case, maybe we should use dual string ? - origin = 'owner' - elif getattr(obj, 'owner_row', ''): - origin = 'owner' - elif getattr(obj, 'admin_row', ''): - origin = 'super-admin' + origin = "owner" + elif getattr(obj, "owner_row", ""): + origin = "owner" + elif getattr(obj, "admin_row", ""): + origin = "super-admin" return origin @@ -152,7 +152,7 @@ def has_superadmin_permission(apiuser): :param apiuser: """ - if HasPermissionAnyApi('hg.admin')(user=apiuser): + if HasPermissionAnyApi("hg.admin")(user=apiuser): return True return False @@ -166,9 +166,8 @@ def validate_repo_permissions(apiuser, repoid, repo, perms): :param repo: :param perms: """ - if not HasRepoPermissionAnyApi(*perms)( - user=apiuser, repo_name=repo.repo_name): - raise JSONRPCError('repository `%s` does not exist' % repoid) + if not HasRepoPermissionAnyApi(*perms)(user=apiuser, repo_name=repo.repo_name): + raise JSONRPCError("repository `%s` does not exist" % repoid) return True @@ -182,10 +181,8 @@ def validate_repo_group_permissions(apiuser, repogroupid, repo_group, perms): :param repo_group: instance of repo_group :param perms: """ - if not HasRepoGroupPermissionAnyApi(*perms)( - user=apiuser, group_name=repo_group.group_name): - raise JSONRPCError( - 'repository group `%s` does not exist' % repogroupid) + if not HasRepoGroupPermissionAnyApi(*perms)(user=apiuser, group_name=repo_group.group_name): + raise JSONRPCError("repository group `%s` does not exist" % repogroupid) return True @@ -198,8 +195,7 @@ def validate_set_owner_permissions(apiuser, owner): owner = get_user_or_error(owner) else: # forbid setting owner for non-admins - raise JSONRPCError( - 'Only RhodeCode super-admin can specify `owner` param') + raise JSONRPCError("Only RhodeCode super-admin can specify `owner` param") return owner @@ -210,6 +206,7 @@ def get_user_or_error(userid): :param userid: """ from rhodecode.model.user import UserModel + user_model = UserModel() if isinstance(userid, int): @@ -221,8 +218,7 @@ def get_user_or_error(userid): user = user_model.get_by_username(userid) if user is None: - raise JSONRPCError( - 'user `{}` does not exist'.format(userid)) + raise JSONRPCError("user `{}` does not exist".format(userid)) return user @@ -233,6 +229,7 @@ def get_repo_or_error(repoid): :param repoid: """ from rhodecode.model.repo import RepoModel + repo_model = RepoModel() if isinstance(repoid, int): @@ -244,8 +241,7 @@ def get_repo_or_error(repoid): repo = repo_model.get_by_repo_name(repoid) if repo is None: - raise JSONRPCError( - 'repository `{}` does not exist'.format(repoid)) + raise JSONRPCError("repository `{}` does not exist".format(repoid)) return repo @@ -256,6 +252,7 @@ def get_repo_group_or_error(repogroupid): :param repogroupid: """ from rhodecode.model.repo_group import RepoGroupModel + repo_group_model = RepoGroupModel() if isinstance(repogroupid, int): @@ -267,8 +264,7 @@ def get_repo_group_or_error(repogroupid): repo_group = repo_group_model.get_by_group_name(repogroupid) if repo_group is None: - raise JSONRPCError( - 'repository group `{}` does not exist'.format(repogroupid)) + raise JSONRPCError("repository group `{}` does not exist".format(repogroupid)) return repo_group @@ -279,6 +275,7 @@ def get_user_group_or_error(usergroupid): :param usergroupid: """ from rhodecode.model.user_group import UserGroupModel + user_group_model = UserGroupModel() if isinstance(usergroupid, int): @@ -290,8 +287,7 @@ def get_user_group_or_error(usergroupid): user_group = user_group_model.get_by_name(usergroupid) if user_group is None: - raise JSONRPCError( - 'user group `{}` does not exist'.format(usergroupid)) + raise JSONRPCError("user group `{}` does not exist".format(usergroupid)) return user_group @@ -305,15 +301,14 @@ def get_perm_or_error(permid, prefix=None): perm = PermissionModel.cls.get_by_key(permid) if perm is None: - msg = f'permission `{permid}` does not exist.' + msg = f"permission `{permid}` does not exist." if prefix: - msg += f' Permission should start with prefix: `{prefix}`' + msg += f" Permission should start with prefix: `{prefix}`" raise JSONRPCError(msg) if prefix: if not perm.permission_name.startswith(prefix): - raise JSONRPCError('permission `%s` is invalid, ' - 'should start with %s' % (permid, prefix)) + raise JSONRPCError("permission `%s` is invalid, should start with %s" % (permid, prefix)) return perm @@ -327,7 +322,7 @@ def get_gist_or_error(gistid): gist = GistModel.cls.get_by_access_id(gistid) if gist is None: - raise JSONRPCError('gist `{}` does not exist'.format(gistid)) + raise JSONRPCError("gist `{}` does not exist".format(gistid)) return gist @@ -342,10 +337,9 @@ def get_pull_request_or_error(pullrequestid): try: pull_request = PullRequestModel().get(int(pullrequestid)) except ValueError: - raise JSONRPCError('pullrequestid must be an integer') + raise JSONRPCError("pullrequestid must be an integer") if not pull_request: - raise JSONRPCError('pull request `{}` does not exist'.format( - pullrequestid)) + raise JSONRPCError("pull request `{}` does not exist".format(pullrequestid)) return pull_request @@ -354,103 +348,106 @@ def build_commit_data(rhodecode_vcs_repo, commit, detail_level): commit1 = commit.first_parent parsed_diff = [] - if detail_level == 'extended': + if detail_level == "extended": for f_path in commit.added_paths: - parsed_diff.append(_get_commit_dict(filename=f_path, op='A')) + parsed_diff.append(_get_commit_dict(filename=f_path, op="A")) for f_path in commit.changed_paths: - parsed_diff.append(_get_commit_dict(filename=f_path, op='M')) + parsed_diff.append(_get_commit_dict(filename=f_path, op="M")) for f_path in commit.removed_paths: - parsed_diff.append(_get_commit_dict(filename=f_path, op='D')) + parsed_diff.append(_get_commit_dict(filename=f_path, op="D")) - elif detail_level == 'full': + elif detail_level == "full": from rhodecode.lib import diffs - _diff = rhodecode_vcs_repo.get_diff(commit1, commit2,) - diff_processor = diffs.DiffProcessor(_diff, diff_format='newdiff', show_full_diff=True) + _diff = rhodecode_vcs_repo.get_diff( + commit1, + commit2, + ) + diff_processor = diffs.DiffProcessor(_diff, diff_format="newdiff", show_full_diff=True) for dp in diff_processor.prepare(): - del dp['stats']['ops'] - _stats = dp['stats'] - parsed_diff.append(_get_commit_dict( - filename=dp['filename'], op=dp['operation'], - new_revision=dp['new_revision'], - old_revision=dp['old_revision'], - raw_diff=dp['raw_diff'], stats=_stats)) + del dp["stats"]["ops"] + _stats = dp["stats"] + parsed_diff.append( + _get_commit_dict( + filename=dp["filename"], + op=dp["operation"], + new_revision=dp["new_revision"], + old_revision=dp["old_revision"], + raw_diff=dp["raw_diff"], + stats=_stats, + ) + ) return parsed_diff def get_commit_or_error(ref, repo): try: - ref_type, _, ref_hash = ref.split(':') + ref_type, _, ref_hash = ref.split(":") except ValueError: raise JSONRPCError( - 'Ref `{ref}` given in a wrong format. Please check the API' - ' documentation for more details'.format(ref=ref)) + "Ref `{ref}` given in a wrong format. Please check the API documentation for more details".format(ref=ref) + ) try: # TODO: dan: refactor this to use repo.scm_instance().get_commit() # once get_commit supports ref_types return get_commit_from_ref_name(repo, ref_hash) except RepositoryError: - raise JSONRPCError(f'Ref `{ref}` does not exist') + raise JSONRPCError(f"Ref `{ref}` does not exist") def _get_ref_hash(repo, type_, name): vcs_repo = repo.scm_instance() - if type_ in ['branch'] and vcs_repo.alias in ('hg', 'git'): + if type_ in ["branch"] and vcs_repo.alias in ("hg", "git"): return vcs_repo.branches[name] - elif type_ in ['bookmark', 'book'] and vcs_repo.alias == 'hg': + elif type_ in ["bookmark", "book"] and vcs_repo.alias == "hg": return vcs_repo.bookmarks[name] else: raise ValueError() def resolve_ref_or_error(ref, repo, allowed_ref_types=None): - allowed_ref_types = allowed_ref_types or ['bookmark', 'book', 'tag', 'branch'] + allowed_ref_types = allowed_ref_types or ["bookmark", "book", "tag", "branch"] def _parse_ref(type_, name, hash_=None): return type_, name, hash_ try: - ref_type, ref_name, ref_hash = _parse_ref(*ref.split(':')) + ref_type, ref_name, ref_hash = _parse_ref(*ref.split(":")) except TypeError: raise JSONRPCError( - 'Ref `{ref}` given in a wrong format. Please check the API' - ' documentation for more details'.format(ref=ref)) + "Ref `{ref}` given in a wrong format. Please check the API documentation for more details".format(ref=ref) + ) if ref_type not in allowed_ref_types: raise JSONRPCError( - 'Ref `{ref}` type is not allowed. ' - 'Only:{allowed_refs} are possible.'.format( - ref=ref, allowed_refs=allowed_ref_types)) + "Ref `{ref}` type is not allowed. Only:{allowed_refs} are possible.".format( + ref=ref, allowed_refs=allowed_ref_types + ) + ) try: ref_hash = ref_hash or _get_ref_hash(repo, ref_type, ref_name) except (KeyError, ValueError): raise JSONRPCError( - 'The specified value:{type}:`{name}` does not exist, or is not allowed.'.format( - type=ref_type, name=ref_name)) + "The specified value:{type}:`{name}` does not exist, or is not allowed.".format( + type=ref_type, name=ref_name + ) + ) - return ':'.join([ref_type, ref_name, ref_hash]) + return ":".join([ref_type, ref_name, ref_hash]) -def _get_commit_dict( - filename, op, new_revision=None, old_revision=None, - raw_diff=None, stats=None): +def _get_commit_dict(filename, op, new_revision=None, old_revision=None, raw_diff=None, stats=None): if stats is None: - stats = { - "added": None, - "binary": None, - "deleted": None - } + stats = {"added": None, "binary": None, "deleted": None} return { "filename": safe_str(filename), "op": op, - # extra details "new_revision": new_revision, "old_revision": old_revision, - "raw_diff": raw_diff, - "stats": stats + "stats": stats, } diff --git a/rhodecode/api/views/deprecated_api.py b/rhodecode/api/views/deprecated_api.py index c961ff2b..2e3dc7a5 100644 --- a/rhodecode/api/views/deprecated_api.py +++ b/rhodecode/api/views/deprecated_api.py @@ -22,6 +22,7 @@ NOTE: Place for deprecated APIs here, if a call needs to be deprecated, please put it here, and point to a new version """ + import logging from rhodecode.api import jsonrpc_method, jsonrpc_deprecated_method @@ -33,11 +34,10 @@ log = logging.getLogger(__name__) # permission check inside @jsonrpc_method() -@jsonrpc_deprecated_method( - use_method='comment_commit', deprecated_at_version='3.4.0') -def changeset_comment(request, apiuser, repoid, revision, message, - userid=Optional(OAttr('apiuser')), - status=Optional(None)): +@jsonrpc_deprecated_method(use_method="comment_commit", deprecated_at_version="3.4.0") +def changeset_comment( + request, apiuser, repoid, revision, message, userid=Optional(OAttr("apiuser")), status=Optional(None) +): """ Set a changeset comment, and optionally change the status of the changeset. @@ -79,22 +79,28 @@ def changeset_comment(request, apiuser, repoid, revision, message, """ from .repo_api import comment_commit - return comment_commit(request=request, - apiuser=apiuser, repoid=repoid, commit_id=revision, - message=message, userid=userid, status=status) + return comment_commit( + request=request, + apiuser=apiuser, + repoid=repoid, + commit_id=revision, + message=message, + userid=userid, + status=status, + ) @jsonrpc_method() -@jsonrpc_deprecated_method( - use_method='get_ip', deprecated_at_version='4.0.0') -def show_ip(request, apiuser, userid=Optional(OAttr('apiuser'))): +@jsonrpc_deprecated_method(use_method="get_ip", deprecated_at_version="4.0.0") +def show_ip(request, apiuser, userid=Optional(OAttr("apiuser"))): from .server_api import get_ip + return get_ip(request=request, apiuser=apiuser, userid=userid) @jsonrpc_method() -@jsonrpc_deprecated_method( - use_method='get_user_locks', deprecated_at_version='4.0.0') -def get_locks(request, apiuser, userid=Optional(OAttr('apiuser'))): +@jsonrpc_deprecated_method(use_method="get_user_locks", deprecated_at_version="4.0.0") +def get_locks(request, apiuser, userid=Optional(OAttr("apiuser"))): from .user_api import get_user_locks - return get_user_locks(request=request, apiuser=apiuser, userid=userid) \ No newline at end of file + + return get_user_locks(request=request, apiuser=apiuser, userid=userid) diff --git a/rhodecode/api/views/gist_api.py b/rhodecode/api/views/gist_api.py index 33cc3f43..7034c130 100644 --- a/rhodecode/api/views/gist_api.py +++ b/rhodecode/api/views/gist_api.py @@ -22,9 +22,7 @@ import time from rhodecode.api import jsonrpc_method, JSONRPCError from rhodecode.api.exc import JSONRPCValidationError -from rhodecode.api.utils import ( - Optional, OAttr, get_gist_or_error, get_user_or_error, - has_superadmin_permission) +from rhodecode.api.utils import Optional, OAttr, get_gist_or_error, get_user_or_error, has_superadmin_permission from rhodecode.model.db import Session, or_ from rhodecode.model.gist import Gist, GistModel @@ -49,18 +47,19 @@ def get_gist(request, apiuser, gistid, content=Optional(False)): if not has_superadmin_permission(apiuser): if gist.gist_owner != apiuser.user_id: - raise JSONRPCError(f'gist `{gistid}` does not exist') + raise JSONRPCError(f"gist `{gistid}` does not exist") data = gist.get_api_data() if content: from rhodecode.model.gist import GistModel + rev, gist_files = GistModel().get_gist_files(gistid) - data['content'] = {x.path: x.str_content for x in gist_files} + data["content"] = {x.path: x.str_content for x in gist_files} return data @jsonrpc_method() -def get_gists(request, apiuser, userid=Optional(OAttr('apiuser'))): +def get_gists(request, apiuser, userid=Optional(OAttr("apiuser"))): """ Get all gists for given user. If userid is empty returned gists are for user who called the api @@ -75,9 +74,7 @@ def get_gists(request, apiuser, userid=Optional(OAttr('apiuser'))): # make sure normal user does not pass someone else userid, # he is not allowed to do that if not isinstance(userid, Optional) and userid != apiuser.user_id: - raise JSONRPCError( - 'userid is not the same as your user' - ) + raise JSONRPCError("userid is not the same as your user") if isinstance(userid, Optional): user_id = apiuser.user_id @@ -85,11 +82,13 @@ def get_gists(request, apiuser, userid=Optional(OAttr('apiuser'))): user_id = get_user_or_error(userid).user_id gists = [] - _gists = Gist().query() \ - .filter(or_( - Gist.gist_expires == -1, Gist.gist_expires >= time.time())) \ - .filter(Gist.gist_owner == user_id) \ + _gists = ( + Gist() + .query() + .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time())) + .filter(Gist.gist_owner == user_id) .order_by(Gist.created_on.desc()) + ) for gist in _gists: gists.append(gist.get_api_data()) return gists @@ -97,11 +96,16 @@ def get_gists(request, apiuser, userid=Optional(OAttr('apiuser'))): @jsonrpc_method() def create_gist( - request, apiuser, files, gistid=Optional(None), - owner=Optional(OAttr('apiuser')), - gist_type=Optional(Gist.GIST_PUBLIC), lifetime=Optional(-1), - acl_level=Optional(Gist.ACL_LEVEL_PUBLIC), - description=Optional('')): + request, + apiuser, + files, + gistid=Optional(None), + owner=Optional(OAttr("apiuser")), + gist_type=Optional(Gist.GIST_PUBLIC), + lifetime=Optional(-1), + acl_level=Optional(Gist.ACL_LEVEL_PUBLIC), + description=Optional(""), +): """ Creates a new Gist. @@ -163,24 +167,25 @@ def create_gist( schema = gist_schema.GistSchema().bind( # bind the given values if it's allowed, however the deferred # validator will still validate it according to other rules - lifetime_options=[lifetime]) + lifetime_options=[lifetime] + ) try: - nodes = gist_schema.nodes_to_sequence( - files, colander_node=schema.get('nodes')) + nodes = gist_schema.nodes_to_sequence(files, colander_node=schema.get("nodes")) - schema_data = schema.deserialize(dict( - gistid=Optional.extract(gistid), - description=Optional.extract(description), - gist_type=Optional.extract(gist_type), - lifetime=lifetime, - gist_acl_level=Optional.extract(acl_level), - nodes=nodes - )) + schema_data = schema.deserialize( + dict( + gistid=Optional.extract(gistid), + description=Optional.extract(description), + gist_type=Optional.extract(gist_type), + lifetime=lifetime, + gist_acl_level=Optional.extract(acl_level), + nodes=nodes, + ) + ) # convert to safer format with just KEYs so we sure no duplicates - schema_data['nodes'] = gist_schema.sequence_to_nodes( - schema_data['nodes'], colander_node=schema.get('nodes')) + schema_data["nodes"] = gist_schema.sequence_to_nodes(schema_data["nodes"], colander_node=schema.get("nodes")) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) @@ -188,20 +193,18 @@ def create_gist( try: gist = GistModel().create( owner=owner, - gist_id=schema_data['gistid'], - description=schema_data['description'], - gist_mapping=schema_data['nodes'], - gist_type=schema_data['gist_type'], - lifetime=schema_data['lifetime'], - gist_acl_level=schema_data['gist_acl_level']) + gist_id=schema_data["gistid"], + description=schema_data["description"], + gist_mapping=schema_data["nodes"], + gist_type=schema_data["gist_type"], + lifetime=schema_data["lifetime"], + gist_acl_level=schema_data["gist_acl_level"], + ) Session().commit() - return { - 'msg': 'created new gist', - 'gist': gist.get_api_data() - } + return {"msg": "created new gist", "gist": gist.get_api_data()} except Exception: - log.exception('Error occurred during creation of gist') - raise JSONRPCError('failed to create gist') + log.exception("Error occurred during creation of gist") + raise JSONRPCError("failed to create gist") @jsonrpc_method() @@ -240,16 +243,12 @@ def delete_gist(request, apiuser, gistid): gist = get_gist_or_error(gistid) if not has_superadmin_permission(apiuser): if gist.gist_owner != apiuser.user_id: - raise JSONRPCError(f'gist `{gistid}` does not exist') + raise JSONRPCError(f"gist `{gistid}` does not exist") try: GistModel().delete(gist) Session().commit() - return { - 'msg': f'deleted gist ID:{gist.gist_access_id}', - 'gist': None - } + return {"msg": f"deleted gist ID:{gist.gist_access_id}", "gist": None} except Exception: - log.exception('Error occured during gist deletion') - raise JSONRPCError('failed to delete gist ID:%s' - % (gist.gist_access_id,)) \ No newline at end of file + log.exception("Error occured during gist deletion") + raise JSONRPCError("failed to delete gist ID:%s" % (gist.gist_access_id,)) diff --git a/rhodecode/api/views/pull_request_api.py b/rhodecode/api/views/pull_request_api.py index ffbc4e6f..72e5ea61 100644 --- a/rhodecode/api/views/pull_request_api.py +++ b/rhodecode/api/views/pull_request_api.py @@ -21,18 +21,25 @@ import logging from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCValidationError from rhodecode.api.utils import ( - has_superadmin_permission, Optional, OAttr, get_repo_or_error, - get_pull_request_or_error, get_commit_or_error, get_user_or_error, - validate_repo_permissions, resolve_ref_or_error, validate_set_owner_permissions) + has_superadmin_permission, + Optional, + OAttr, + get_repo_or_error, + get_pull_request_or_error, + get_commit_or_error, + get_user_or_error, + validate_repo_permissions, + resolve_ref_or_error, + validate_set_owner_permissions, +) from rhodecode.lib import channelstream -from rhodecode.lib.auth import (HasRepoPermissionAnyApi) +from rhodecode.lib.auth import HasRepoPermissionAnyApi from rhodecode.lib.base import vcs_operation_context from rhodecode.lib.utils2 import str2bool from rhodecode.lib.vcs.backends.base import unicode_to_reference from rhodecode.model.changeset_status import ChangesetStatusModel from rhodecode.model.comment import CommentsModel -from rhodecode.model.db import ( - Session, ChangesetStatus, ChangesetComment, PullRequest, PullRequestReviewers) +from rhodecode.model.db import Session, ChangesetStatus, ChangesetComment, PullRequest, PullRequestReviewers from rhodecode.model.pull_request import PullRequestModel, MergeCheck from rhodecode.model.settings import SettingsModel from rhodecode.model.validation_schema import Invalid @@ -42,8 +49,7 @@ log = logging.getLogger(__name__) @jsonrpc_method() -def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None), - merge_state=Optional(False)): +def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None), merge_state=Optional(False)): """ Get a pull request based on the given ID. @@ -133,8 +139,7 @@ def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None), repo = pull_request.target_repo if not PullRequestModel().check_user_read(pull_request, apiuser, api=True): - raise JSONRPCError('repository `%s` or pull request `%s` ' - 'does not exist' % (repoid, pullrequestid)) + raise JSONRPCError("repository `%s` or pull request `%s` does not exist" % (repoid, pullrequestid)) # NOTE(marcink): only calculate and return merge state if the pr state is 'created' # otherwise we can lock the repo on calculation of merge state while update/merge @@ -146,8 +151,7 @@ def get_pull_request(request, apiuser, pullrequestid, repoid=Optional(None), @jsonrpc_method() -def get_pull_requests(request, apiuser, repoid, status=Optional('new'), - merge_state=Optional(False)): +def get_pull_requests(request, apiuser, repoid, status=Optional("new"), merge_state=Optional(False)): """ Get all pull requests from the repository specified in `repoid`. @@ -237,21 +241,21 @@ def get_pull_requests(request, apiuser, repoid, status=Optional('new'), repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): _perms = ( - 'repository.admin', 'repository.write', 'repository.read',) + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) status = Optional.extract(status) merge_state = Optional.extract(merge_state, binary=True) - pull_requests = PullRequestModel().get_all(repo, statuses=[status], - order_by='id', order_dir='desc') + pull_requests = PullRequestModel().get_all(repo, statuses=[status], order_by="id", order_dir="desc") data = [pr.get_api_data(with_merge_state=merge_state) for pr in pull_requests] return data @jsonrpc_method() -def merge_pull_request( - request, apiuser, pullrequestid, repoid=Optional(None), - userid=Optional(OAttr('apiuser'))): +def merge_pull_request(request, apiuser, pullrequestid, repoid=Optional(None), userid=Optional(OAttr("apiuser"))): """ Merge the pull request specified by `pullrequestid` into its target repository. @@ -293,23 +297,22 @@ def merge_pull_request( auth_user = apiuser if not isinstance(userid, Optional): - is_repo_admin = HasRepoPermissionAnyApi('repository.admin')( - user=apiuser, repo_name=repo.repo_name) + is_repo_admin = HasRepoPermissionAnyApi("repository.admin")(user=apiuser, repo_name=repo.repo_name) if has_superadmin_permission(apiuser) or is_repo_admin: apiuser = get_user_or_error(userid) auth_user = apiuser.AuthUser() else: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") if pull_request.pull_request_state != PullRequest.STATE_CREATED: raise JSONRPCError( - 'Operation forbidden because pull request is in state {}, ' - 'only state {} is allowed.'.format( - pull_request.pull_request_state, PullRequest.STATE_CREATED)) + "Operation forbidden because pull request is in state {}, only state {} is allowed.".format( + pull_request.pull_request_state, PullRequest.STATE_CREATED + ) + ) with pull_request.set_state(PullRequest.STATE_UPDATING): - check = MergeCheck.validate(pull_request, auth_user=auth_user, - translator=request.translate) + check = MergeCheck.validate(pull_request, auth_user=auth_user, translator=request.translate) merge_possible = not check.failed if not merge_possible: @@ -318,18 +321,19 @@ def merge_pull_request( error_msg = request.translate(error_msg) error_messages.append(error_msg) - reasons = ','.join(error_messages) - raise JSONRPCError( - f'merge not possible for following reasons: {reasons}') + reasons = ",".join(error_messages) + raise JSONRPCError(f"merge not possible for following reasons: {reasons}") target_repo = pull_request.target_repo extras = vcs_operation_context( - request.environ, repo_name=target_repo.repo_name, - username=auth_user.username, action='push', - scm=target_repo.repo_type) + request.environ, + repo_name=target_repo.repo_name, + username=auth_user.username, + action="push", + scm=target_repo.repo_type, + ) with pull_request.set_state(PullRequest.STATE_UPDATING): - merge_response = PullRequestModel().merge_repo( - pull_request, apiuser, extras=extras) + merge_response = PullRequestModel().merge_repo(pull_request, apiuser, extras=extras) if merge_response.executed: PullRequestModel().close_pull_request(pull_request.pull_request_id, auth_user) @@ -339,14 +343,13 @@ def merge_pull_request( # commit id. It is now contained in the merge reference object. To be # backwards compatible we have to extract it again. merge_response = merge_response.asdict() - merge_response['merge_commit_id'] = merge_response['merge_ref'].commit_id + merge_response["merge_commit_id"] = merge_response["merge_ref"].commit_id return merge_response @jsonrpc_method() -def get_pull_request_comments( - request, apiuser, pullrequestid, repoid=Optional(None)): +def get_pull_request_comments(request, apiuser, pullrequestid, repoid=Optional(None)): """ Get all comments of pull request specified with the `pullrequestid` @@ -394,22 +397,15 @@ def get_pull_request_comments( else: repo = pull_request.target_repo - if not PullRequestModel().check_user_read( - pull_request, apiuser, api=True): - raise JSONRPCError('repository `%s` or pull request `%s` ' - 'does not exist' % (repoid, pullrequestid)) + if not PullRequestModel().check_user_read(pull_request, apiuser, api=True): + raise JSONRPCError("repository `%s` or pull request `%s` does not exist" % (repoid, pullrequestid)) - (pull_request_latest, - pull_request_at_ver, - pull_request_display_obj, - at_version) = PullRequestModel().get_pr_version( - pull_request.pull_request_id, version=None) + (pull_request_latest, pull_request_at_ver, pull_request_display_obj, at_version) = ( + PullRequestModel().get_pr_version(pull_request.pull_request_id, version=None) + ) versions = pull_request_display_obj.versions() - ver_map = { - ver.pull_request_version_id: cnt - for cnt, ver in enumerate(versions, 1) - } + ver_map = {ver.pull_request_version_id: cnt for cnt, ver in enumerate(versions, 1)} # GENERAL COMMENTS with versions # q = CommentsModel()._all_general_comments_of_pull_request(pull_request) @@ -426,25 +422,24 @@ def get_pull_request_comments( full_data = comment.get_api_data() pr_version_id = None if comment.pull_request_version_id: - pr_version_id = 'v{}'.format( - ver_map[comment.pull_request_version_id]) + pr_version_id = "v{}".format(ver_map[comment.pull_request_version_id]) # sanitize some entries - full_data['pull_request_version'] = pr_version_id - full_data['comment_author'] = { - 'username': full_data['comment_author'].username, - 'full_name_or_username': full_data['comment_author'].full_name_or_username, - 'active': full_data['comment_author'].active, + full_data["pull_request_version"] = pr_version_id + full_data["comment_author"] = { + "username": full_data["comment_author"].username, + "full_name_or_username": full_data["comment_author"].full_name_or_username, + "active": full_data["comment_author"].active, } - if full_data['comment_status']: - full_data['comment_status'] = { - 'status': full_data['comment_status'][0].status, - 'status_lbl': full_data['comment_status'][0].status_lbl, + if full_data["comment_status"]: + full_data["comment_status"] = { + "status": full_data["comment_status"][0].status, + "status_lbl": full_data["comment_status"][0].status_lbl, } else: - full_data['comment_status'] = {} + full_data["comment_status"] = {} data.append(full_data) return data @@ -452,11 +447,19 @@ def get_pull_request_comments( @jsonrpc_method() def comment_pull_request( - request, apiuser, pullrequestid, repoid=Optional(None), - message=Optional(None), commit_id=Optional(None), status=Optional(None), - comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), - resolves_comment_id=Optional(None), extra_recipients=Optional([]), - userid=Optional(OAttr('apiuser')), send_email=Optional(True)): + request, + apiuser, + pullrequestid, + repoid=Optional(None), + message=Optional(None), + commit_id=Optional(None), + status=Optional(None), + comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), + resolves_comment_id=Optional(None), + extra_recipients=Optional([]), + userid=Optional(OAttr("apiuser")), + send_email=Optional(True), +): """ Comment on the pull request specified with the `pullrequestid`, in the |repo| specified by the `repoid`, and optionally change the @@ -514,20 +517,18 @@ def comment_pull_request( db_repo_name = repo.repo_name auth_user = apiuser if not isinstance(userid, Optional): - is_repo_admin = HasRepoPermissionAnyApi('repository.admin')( - user=apiuser, repo_name=db_repo_name) + is_repo_admin = HasRepoPermissionAnyApi("repository.admin")(user=apiuser, repo_name=db_repo_name) if has_superadmin_permission(apiuser) or is_repo_admin: apiuser = get_user_or_error(userid) auth_user = apiuser.AuthUser() else: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") if pull_request.is_closed(): - raise JSONRPCError(f'pull request `{pullrequestid}` comment failed, pull request is closed') + raise JSONRPCError(f"pull request `{pullrequestid}` comment failed, pull request is closed") - if not PullRequestModel().check_user_read( - pull_request, apiuser, api=True): - raise JSONRPCError(f'repository `{repoid}` does not exist') + if not PullRequestModel().check_user_read(pull_request, apiuser, api=True): + raise JSONRPCError(f"repository `{repoid}` does not exist") message = Optional.extract(message) status = Optional.extract(status) commit_id = Optional.extract(commit_id) @@ -537,43 +538,39 @@ def comment_pull_request( send_email = Optional.extract(send_email, binary=True) if not message and not status: - raise JSONRPCError( - 'Both message and status parameters are missing. ' - 'At least one is required.') + raise JSONRPCError("Both message and status parameters are missing. At least one is required.") if status and status not in (st[0] for st in ChangesetStatus.STATUSES): - raise JSONRPCError(f'Unknown comment status: `{status}`') + raise JSONRPCError(f"Unknown comment status: `{status}`") if commit_id and commit_id not in pull_request.revisions: - raise JSONRPCError(f'Invalid commit_id `{commit_id}` for this pull request.') + raise JSONRPCError(f"Invalid commit_id `{commit_id}` for this pull request.") - allowed_to_change_status = PullRequestModel().check_user_change_status( - pull_request, apiuser) + allowed_to_change_status = PullRequestModel().check_user_change_status(pull_request, apiuser) # if commit_id is passed re-validated if user is allowed to change status # based on the latest commit_id from the PR if commit_id: commit_idx = pull_request.revisions.index(commit_id) if commit_idx != 0: - log.warning('Resetting allowed_to_change_status = False because commit is NOT the latest in pull-request') + log.warning("Resetting allowed_to_change_status = False because commit is NOT the latest in pull-request") allowed_to_change_status = False if resolves_comment_id: comment = ChangesetComment.get(resolves_comment_id) if not comment: - raise JSONRPCError(f'Invalid resolves_comment_id `{resolves_comment_id}` for this pull request.') + raise JSONRPCError(f"Invalid resolves_comment_id `{resolves_comment_id}` for this pull request.") if comment.comment_type != ChangesetComment.COMMENT_TYPE_TODO: - raise JSONRPCError(f'Comment `{resolves_comment_id}` is wrong type for setting status to resolved.') + raise JSONRPCError(f"Comment `{resolves_comment_id}` is wrong type for setting status to resolved.") text = message status_label = ChangesetStatus.get_status_lbl(status) if status and allowed_to_change_status: - st_message = ('Status change %(transition_icon)s %(status)s' - % {'transition_icon': '>', 'status': status_label}) + st_message = "Status change %(transition_icon)s %(status)s" % {"transition_icon": ">", "status": status_label} text = message or st_message rc_config = SettingsModel().get_all_settings() - renderer = rc_config.get('rhodecode_markup_renderer', 'rst') + renderer = rc_config.get("rhodecode_markup_renderer", "rst") status_change = status and allowed_to_change_status comment = CommentsModel().create( @@ -591,7 +588,7 @@ def comment_pull_request( resolves_comment_id=resolves_comment_id, auth_user=auth_user, extra_recipients=extra_recipients, - send_email=send_email + send_email=send_email, ) is_inline = comment.is_inline @@ -603,15 +600,13 @@ def comment_pull_request( status, apiuser.user_id, comment, - pull_request=pull_request.pull_request_id + pull_request=pull_request.pull_request_id, ) Session().flush() Session().commit() - PullRequestModel().trigger_pull_request_hook( - pull_request, apiuser, 'comment', - data={'comment': comment}) + PullRequestModel().trigger_pull_request_hook(pull_request, apiuser, "comment", data={"comment": comment}) if allowed_to_change_status and status: # we now calculate the status of pull request, and based on that @@ -619,24 +614,26 @@ def comment_pull_request( calculated_status = pull_request.calculated_review_status() if old_calculated_status != calculated_status: PullRequestModel().trigger_pull_request_hook( - pull_request, apiuser, 'review_status_change', - data={'status': calculated_status}) + pull_request, apiuser, "review_status_change", data={"status": calculated_status} + ) data = { - 'pull_request_id': pull_request.pull_request_id, - 'comment_id': comment.comment_id if comment else None, - 'status': {'given': status, 'was_changed': status_change}, + "pull_request_id": pull_request.pull_request_id, + "comment_id": comment.comment_id if comment else None, + "status": {"given": status, "was_changed": status_change}, } - comment_broadcast_channel = channelstream.comment_channel( - db_repo_name, pull_request_obj=pull_request) + comment_broadcast_channel = channelstream.comment_channel(db_repo_name, pull_request_obj=pull_request) comment_data = data - comment_type = 'inline' if is_inline else 'general' + comment_type = "inline" if is_inline else "general" channelstream.comment_channelstream_push( - request, comment_broadcast_channel, apiuser, - _('posted a new {} comment').format(comment_type), - comment_data=comment_data) + request, + comment_broadcast_channel, + apiuser, + _("posted a new {} comment").format(comment_type), + comment_data=comment_data, + ) return data @@ -650,17 +647,26 @@ def _reviewers_validation(obj_list): # validate users for reviewer_object in reviewer_objects: - user = get_user_or_error(reviewer_object['username']) - reviewer_object['user_id'] = user.user_id + user = get_user_or_error(reviewer_object["username"]) + reviewer_object["user_id"] = user.user_id return reviewer_objects @jsonrpc_method() def create_pull_request( - request, apiuser, source_repo, target_repo, source_ref, target_ref, - owner=Optional(OAttr('apiuser')), title=Optional(''), description=Optional(''), - description_renderer=Optional(''), - reviewers=Optional(None), observers=Optional(None)): + request, + apiuser, + source_repo, + target_repo, + source_ref, + target_ref, + owner=Optional(OAttr("apiuser")), + title=Optional(""), + description=Optional(""), + description_renderer=Optional(""), + reviewers=Optional(None), + observers=Optional(None), +): """ Creates a new pull request. @@ -710,7 +716,11 @@ def create_pull_request( source_db_repo = get_repo_or_error(source_repo) target_db_repo = get_repo_or_error(target_repo) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write', 'repository.read',) + _perms = ( + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, source_repo, source_db_repo, _perms) owner = validate_set_owner_permissions(apiuser, owner) @@ -731,8 +741,9 @@ def create_pull_request( if observer_objects: observer_objects = _reviewers_validation(reviewer_objects) - get_default_reviewers_data, validate_default_reviewers, validate_observers = \ + get_default_reviewers_data, validate_default_reviewers, validate_observers = ( PullRequestModel().get_reviewer_functions() + ) source_ref_obj = unicode_to_reference(full_source_ref) target_ref_obj = unicode_to_reference(full_target_ref) @@ -747,55 +758,47 @@ def create_pull_request( ) # now MERGE our given with the calculated from the default rules - just_reviewers = [ - x for x in default_reviewers_data['reviewers'] - if x['role'] == PullRequestReviewers.ROLE_REVIEWER] + just_reviewers = [x for x in default_reviewers_data["reviewers"] if x["role"] == PullRequestReviewers.ROLE_REVIEWER] reviewer_objects = just_reviewers + reviewer_objects try: - reviewers = validate_default_reviewers( - reviewer_objects, default_reviewers_data) + reviewers = validate_default_reviewers(reviewer_objects, default_reviewers_data) except ValueError as e: - raise JSONRPCError(f'Reviewers Validation: {e}') + raise JSONRPCError(f"Reviewers Validation: {e}") # now MERGE our given with the calculated from the default rules - just_observers = [ - x for x in default_reviewers_data['reviewers'] - if x['role'] == PullRequestReviewers.ROLE_OBSERVER] + just_observers = [x for x in default_reviewers_data["reviewers"] if x["role"] == PullRequestReviewers.ROLE_OBSERVER] observer_objects = just_observers + observer_objects try: - observers = validate_observers( - observer_objects, default_reviewers_data) + observers = validate_observers(observer_objects, default_reviewers_data) except ValueError as e: - raise JSONRPCError(f'Observer Validation: {e}') + raise JSONRPCError(f"Observer Validation: {e}") title = Optional.extract(title) if not title: title_source_ref = source_ref_obj.name title = PullRequestModel().generate_pullrequest_title( - source=source_repo, - source_ref=title_source_ref, - target=target_repo + source=source_repo, source_ref=title_source_ref, target=target_repo ) - diff_info = default_reviewers_data['diff_info'] - common_ancestor_id = diff_info['ancestor'] + diff_info = default_reviewers_data["diff_info"] + common_ancestor_id = diff_info["ancestor"] # NOTE(marcink): reversed is consistent with how we open it in the WEB interface - commits = [commit['commit_id'] for commit in reversed(diff_info['commits'])] + commits = [commit["commit_id"] for commit in reversed(diff_info["commits"])] if not common_ancestor_id: - raise JSONRPCError('no common ancestor found between specified references') + raise JSONRPCError("no common ancestor found between specified references") if not commits: - raise JSONRPCError('no commits found for merge between specified references') + raise JSONRPCError("no commits found for merge between specified references") # recalculate target ref based on ancestor - full_target_ref = ':'.join((target_ref_obj.type, target_ref_obj.name, common_ancestor_id)) + full_target_ref = ":".join((target_ref_obj.type, target_ref_obj.name, common_ancestor_id)) # fetch renderer, if set fallback to plain in case of PR rc_config = SettingsModel().get_all_settings() - default_system_renderer = rc_config.get('rhodecode_markup_renderer', 'plain') + default_system_renderer = rc_config.get("rhodecode_markup_renderer", "plain") description = Optional.extract(description) description_renderer = Optional.extract(description_renderer) or default_system_renderer @@ -813,22 +816,30 @@ def create_pull_request( description=description, description_renderer=description_renderer, reviewer_data=default_reviewers_data, - auth_user=apiuser + auth_user=apiuser, ) Session().commit() data = { - 'msg': f'Created new pull request `{title}`', - 'pull_request_id': pull_request.pull_request_id, + "msg": f"Created new pull request `{title}`", + "pull_request_id": pull_request.pull_request_id, } return data @jsonrpc_method() def update_pull_request( - request, apiuser, pullrequestid, repoid=Optional(None), - title=Optional(''), description=Optional(''), description_renderer=Optional(''), - reviewers=Optional(None), observers=Optional(None), update_commits=Optional(None)): + request, + apiuser, + pullrequestid, + repoid=Optional(None), + title=Optional(""), + description=Optional(""), + description_renderer=Optional(""), + reviewers=Optional(None), + observers=Optional(None), + update_commits=Optional(None), +): """ Updates a pull request. @@ -898,15 +909,10 @@ def update_pull_request( else: repo = pull_request.target_repo - if not PullRequestModel().check_user_update( - pull_request, apiuser, api=True): - raise JSONRPCError( - 'pull request `{}` update failed, no permission to update.'.format( - pullrequestid)) + if not PullRequestModel().check_user_update(pull_request, apiuser, api=True): + raise JSONRPCError("pull request `{}` update failed, no permission to update.".format(pullrequestid)) if pull_request.is_closed(): - raise JSONRPCError( - 'pull request `{}` update failed, pull request is closed'.format( - pullrequestid)) + raise JSONRPCError("pull request `{}` update failed, pull request is closed".format(pullrequestid)) reviewer_objects = Optional.extract(reviewers) or [] observer_objects = Optional.extract(observers) or [] @@ -923,7 +929,8 @@ def update_pull_request( title or pull_request.title, description or pull_request.description, description_renderer or pull_request.description_renderer, - apiuser) + apiuser, + ) Session().commit() title_changed = True @@ -932,18 +939,17 @@ def update_pull_request( # Update commits commits_changed = False if str2bool(Optional.extract(update_commits)): - if pull_request.pull_request_state != PullRequest.STATE_CREATED: raise JSONRPCError( - 'Operation forbidden because pull request is in state {}, ' - 'only state {} is allowed.'.format( - pull_request.pull_request_state, PullRequest.STATE_CREATED)) + "Operation forbidden because pull request is in state {}, only state {} is allowed.".format( + pull_request.pull_request_state, PullRequest.STATE_CREATED + ) + ) with pull_request.set_state(PullRequest.STATE_UPDATING): if PullRequestModel().has_valid_update_type(pull_request): db_user = apiuser.get_instance() - update_response = PullRequestModel().update_commits( - pull_request, db_user) + update_response = PullRequestModel().update_commits(pull_request, db_user) commit_changes = update_response.changes or commit_changes Session().commit() commits_changed = True @@ -959,14 +965,13 @@ def update_pull_request( # re-use stored rules default_reviewers_data = pull_request.reviewer_data - __, validate_default_reviewers, validate_observers = \ - PullRequestModel().get_reviewer_functions() + __, validate_default_reviewers, validate_observers = PullRequestModel().get_reviewer_functions() if reviewer_objects: try: reviewers = validate_default_reviewers(reviewer_objects, default_reviewers_data) except ValueError as e: - raise JSONRPCError(f'Reviewers Validation: {e}') + raise JSONRPCError(f"Reviewers Validation: {e}") else: reviewers = [] @@ -974,7 +979,7 @@ def update_pull_request( try: observers = validate_default_reviewers(reviewer_objects, default_reviewers_data) except ValueError as e: - raise JSONRPCError(f'Observer Validation: {e}') + raise JSONRPCError(f"Observer Validation: {e}") else: observers = [] @@ -982,33 +987,31 @@ def update_pull_request( reviewers_changes = {"added": [], "removed": []} if reviewers: old_calculated_status = pull_request.calculated_review_status() - added_reviewers, removed_reviewers = \ - PullRequestModel().update_reviewers(pull_request, reviewers, apiuser.get_instance()) + added_reviewers, removed_reviewers = PullRequestModel().update_reviewers( + pull_request, reviewers, apiuser.get_instance() + ) - reviewers_changes['added'] = sorted( - [get_user_or_error(n).username for n in added_reviewers]) - reviewers_changes['removed'] = sorted( - [get_user_or_error(n).username for n in removed_reviewers]) + reviewers_changes["added"] = sorted([get_user_or_error(n).username for n in added_reviewers]) + reviewers_changes["removed"] = sorted([get_user_or_error(n).username for n in removed_reviewers]) Session().commit() # trigger status changed if change in reviewers changes the status calculated_status = pull_request.calculated_review_status() if old_calculated_status != calculated_status: PullRequestModel().trigger_pull_request_hook( - pull_request, apiuser, 'review_status_change', - data={'status': calculated_status}) + pull_request, apiuser, "review_status_change", data={"status": calculated_status} + ) reviewers_changed = True observers_changed = False observers_changes = {"added": [], "removed": []} if observers: - added_observers, removed_observers = \ - PullRequestModel().update_observers(pull_request, observers, apiuser.get_instance()) + added_observers, removed_observers = PullRequestModel().update_observers( + pull_request, observers, apiuser.get_instance() + ) - observers_changes['added'] = sorted( - [get_user_or_error(n).username for n in added_observers]) - observers_changes['removed'] = sorted( - [get_user_or_error(n).username for n in removed_observers]) + observers_changes["added"] = sorted([get_user_or_error(n).username for n in added_observers]) + observers_changes["removed"] = sorted([get_user_or_error(n).username for n in removed_observers]) Session().commit() reviewers_changed = True @@ -1016,16 +1019,15 @@ def update_pull_request( # push changed to channelstream if commits_changed or reviewers_changed or observers_changed: pr_broadcast_channel = channelstream.pr_channel(pull_request) - msg = 'Pull request was updated.' - channelstream.pr_update_channelstream_push( - request, pr_broadcast_channel, apiuser, msg) + msg = "Pull request was updated." + channelstream.pr_update_channelstream_push(request, pr_broadcast_channel, apiuser, msg) data = { - 'msg': f'Updated pull request `{pull_request.pull_request_id}`', - 'pull_request': pull_request.get_api_data(), - 'updated_commits': commit_changes, - 'updated_reviewers': reviewers_changes, - 'updated_observers': observers_changes, + "msg": f"Updated pull request `{pull_request.pull_request_id}`", + "pull_request": pull_request.get_api_data(), + "updated_commits": commit_changes, + "updated_reviewers": reviewers_changes, + "updated_observers": observers_changes, } return data @@ -1033,8 +1035,8 @@ def update_pull_request( @jsonrpc_method() def close_pull_request( - request, apiuser, pullrequestid, repoid=Optional(None), - userid=Optional(OAttr('apiuser')), message=Optional('')): + request, apiuser, pullrequestid, repoid=Optional(None), userid=Optional(OAttr("apiuser")), message=Optional("") +): """ Close the pull request specified by `pullrequestid`. @@ -1072,40 +1074,36 @@ def close_pull_request( else: repo = pull_request.target_repo - is_repo_admin = HasRepoPermissionAnyApi('repository.admin')( - user=apiuser, repo_name=repo.repo_name) + is_repo_admin = HasRepoPermissionAnyApi("repository.admin")(user=apiuser, repo_name=repo.repo_name) if not isinstance(userid, Optional): if has_superadmin_permission(apiuser) or is_repo_admin: apiuser = get_user_or_error(userid) else: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") if pull_request.is_closed(): - raise JSONRPCError( - f'pull request `{pullrequestid}` is already closed') + raise JSONRPCError(f"pull request `{pullrequestid}` is already closed") # only owner or admin or person with write permissions - allowed_to_close = PullRequestModel().check_user_update( - pull_request, apiuser, api=True) + allowed_to_close = PullRequestModel().check_user_update(pull_request, apiuser, api=True) if not allowed_to_close: - raise JSONRPCError( - 'pull request `{}` close failed, no permission to close.'.format( - pullrequestid)) + raise JSONRPCError("pull request `{}` close failed, no permission to close.".format(pullrequestid)) # message we're using to close the PR, else it's automatically generated message = Optional.extract(message) # finally close the PR, with proper message comment comment, status = PullRequestModel().close_pull_request_with_comment( - pull_request, apiuser, repo, message=message, auth_user=apiuser) + pull_request, apiuser, repo, message=message, auth_user=apiuser + ) status_lbl = ChangesetStatus.get_status_lbl(status) Session().commit() data = { - 'pull_request_id': pull_request.pull_request_id, - 'close_status': status_lbl, - 'closed': True, + "pull_request_id": pull_request.pull_request_id, + "close_status": status_lbl, + "closed": True, } return data diff --git a/rhodecode/api/views/repo_api.py b/rhodecode/api/views/repo_api.py index 60ee6b64..4dd11cee 100644 --- a/rhodecode/api/views/repo_api.py +++ b/rhodecode/api/views/repo_api.py @@ -20,31 +20,33 @@ import logging import time import rhodecode -from rhodecode.api import ( - jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError) +from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError from rhodecode.api.utils import ( - has_superadmin_permission, Optional, OAttr, get_repo_or_error, - get_user_group_or_error, get_user_or_error, validate_repo_permissions, - get_perm_or_error, parse_args, get_origin, build_commit_data, - validate_set_owner_permissions) + has_superadmin_permission, + Optional, + OAttr, + get_repo_or_error, + get_user_group_or_error, + get_user_or_error, + validate_repo_permissions, + get_perm_or_error, + parse_args, + get_origin, + build_commit_data, + validate_set_owner_permissions, +) from rhodecode.lib import audit_logger, rc_cache, channelstream from rhodecode.lib import repo_maintenance -from rhodecode.lib.auth import ( - HasPermissionAnyApi, HasUserGroupPermissionAnyApi, - HasRepoPermissionAnyApi) +from rhodecode.lib.auth import HasPermissionAnyApi, HasUserGroupPermissionAnyApi, HasRepoPermissionAnyApi from rhodecode.lib.celerylib.utils import get_task_id -from rhodecode.lib.utils2 import ( - str2bool, time_to_datetime, safe_str, safe_int) +from rhodecode.lib.utils2 import str2bool, time_to_datetime, safe_str, safe_int from rhodecode.lib.ext_json import json -from rhodecode.lib.exceptions import ( - StatusChangeOnClosedPullRequestError, CommentVersionMismatch) +from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError, CommentVersionMismatch from rhodecode.lib.vcs import RepositoryError from rhodecode.lib.vcs.exceptions import NodeDoesNotExistError from rhodecode.model.changeset_status import ChangesetStatusModel from rhodecode.model.comment import CommentsModel -from rhodecode.model.db import ( - Session, ChangesetStatus, RepositoryField, Repository, RepoGroup, - ChangesetComment) +from rhodecode.model.db import Session, ChangesetStatus, RepositoryField, Repository, RepoGroup, ChangesetComment from rhodecode.model.permission import PermissionModel from rhodecode.model.pull_request import PullRequestModel from rhodecode.model.repo import RepoModel @@ -171,37 +173,38 @@ def get_repo(request, apiuser, repoid, cache=Optional(True)): else: # check if we have at least read permission for this repo ! _perms = ( - 'repository.admin', 'repository.write', 'repository.read',) + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) permissions = [] for _user in repo.permissions(): user_data = { - 'name': _user.username, - 'permission': _user.permission, - 'origin': get_origin(_user), - 'type': "user", + "name": _user.username, + "permission": _user.permission, + "origin": get_origin(_user), + "type": "user", } permissions.append(user_data) for _user_group in repo.permission_user_groups(): user_group_data = { - 'name': _user_group.users_group_name, - 'permission': _user_group.permission, - 'origin': get_origin(_user_group), - 'type': "user_group", + "name": _user_group.users_group_name, + "permission": _user_group.permission, + "origin": get_origin(_user_group), + "type": "user_group", } permissions.append(user_group_data) - following_users = [ - user.user.get_api_data(include_secrets=include_secrets) - for user in repo.followers] + following_users = [user.user.get_api_data(include_secrets=include_secrets) for user in repo.followers] if not cache: repo.update_commit_cache() data = repo.get_api_data(include_secrets=include_secrets) - data['permissions'] = permissions - data['followers'] = following_users + data["permissions"] = permissions + data["followers"] = following_users return data @@ -252,8 +255,12 @@ def get_repos(request, apiuser, root=Optional(None), traverse=Optional(True)): """ include_secrets = has_superadmin_permission(apiuser) - _perms = ('repository.read', 'repository.write', 'repository.admin',) - extras = {'user': apiuser} + _perms = ( + "repository.read", + "repository.write", + "repository.admin", + ) + extras = {"user": apiuser} root = Optional.extract(root) traverse = Optional.extract(traverse, binary=True) @@ -262,8 +269,7 @@ def get_repos(request, apiuser, root=Optional(None), traverse=Optional(True)): # verify parent existance, if it's empty return an error parent = RepoGroup.get_by_group_name(root) if not parent: - raise JSONRPCError( - f'Root repository group `{root}` does not exist') + raise JSONRPCError(f"Root repository group `{root}` does not exist") if traverse: repos = RepoModel().get_repos_for_root(root=root, traverse=traverse) @@ -277,13 +283,11 @@ def get_repos(request, apiuser, root=Optional(None), traverse=Optional(True)): repos = RepoModel().get_repos_for_root(root=None) repo_list = RepoList(repos, perm_set=_perms, extra_kwargs=extras) - return [repo.get_api_data(include_secrets=include_secrets) - for repo in repo_list] + return [repo.get_api_data(include_secrets=include_secrets) for repo in repo_list] @jsonrpc_method() -def get_repo_changeset(request, apiuser, repoid, revision, - details=Optional('basic')): +def get_repo_changeset(request, apiuser, repoid, revision, details=Optional("basic")): """ Returns information about a changeset. @@ -306,33 +310,34 @@ def get_repo_changeset(request, apiuser, repoid, revision, """ repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write', 'repository.read',) + _perms = ( + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) changes_details = Optional.extract(details) - _changes_details_types = ['basic', 'extended', 'full'] + _changes_details_types = ["basic", "extended", "full"] if changes_details not in _changes_details_types: - raise JSONRPCError( - 'ret_type must be one of %s' % ( - ','.join(_changes_details_types))) + raise JSONRPCError("ret_type must be one of %s" % (",".join(_changes_details_types))) vcs_repo = repo.scm_instance() - pre_load = ['author', 'branch', 'date', 'message', 'parents', 'status', '_commit'] + pre_load = ["author", "branch", "date", "message", "parents", "status", "_commit"] try: commit = repo.get_commit(commit_id=revision, pre_load=pre_load) except TypeError as e: raise JSONRPCError(safe_str(e)) _cs_json = commit.__json__() - _cs_json['diff'] = build_commit_data(vcs_repo, commit, changes_details) - if changes_details == 'full': - _cs_json['refs'] = commit._get_refs() + _cs_json["diff"] = build_commit_data(vcs_repo, commit, changes_details) + if changes_details == "full": + _cs_json["refs"] = commit._get_refs() return _cs_json @jsonrpc_method() -def get_repo_changesets(request, apiuser, repoid, start_rev, limit, - details=Optional('basic')): +def get_repo_changesets(request, apiuser, repoid, start_rev, limit, details=Optional("basic")): """ Returns a set of commits limited by the number starting from the `start_rev` option. @@ -364,53 +369,61 @@ def get_repo_changesets(request, apiuser, repoid, start_rev, limit, """ repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write', 'repository.read',) + _perms = ( + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) changes_details = Optional.extract(details) - _changes_details_types = ['basic', 'extended', 'full'] + _changes_details_types = ["basic", "extended", "full"] if changes_details not in _changes_details_types: - raise JSONRPCError( - 'ret_type must be one of %s' % ( - ','.join(_changes_details_types))) + raise JSONRPCError("ret_type must be one of %s" % (",".join(_changes_details_types))) limit = int(limit) - pre_load = ['author', 'branch', 'date', 'message', 'parents', 'status', '_commit'] + pre_load = ["author", "branch", "date", "message", "parents", "status", "_commit"] vcs_repo = repo.scm_instance() # SVN needs a special case to distinguish its index and commit id - if vcs_repo and vcs_repo.alias == 'svn' and (start_rev == '0'): + if vcs_repo and vcs_repo.alias == "svn" and (start_rev == "0"): start_rev = vcs_repo.commit_ids[0] try: - commits = vcs_repo.get_commits( - start_id=start_rev, pre_load=pre_load, translate_tags=False) + commits = vcs_repo.get_commits(start_id=start_rev, pre_load=pre_load, translate_tags=False) except TypeError as e: raise JSONRPCError(safe_str(e)) except Exception: - log.exception('Fetching of commits failed') - raise JSONRPCError('Error occurred during commit fetching') + log.exception("Fetching of commits failed") + raise JSONRPCError("Error occurred during commit fetching") ret = [] for cnt, commit in enumerate(commits): if cnt >= limit != -1: break _cs_json = commit.__json__() - _cs_json['diff'] = build_commit_data(vcs_repo, commit, changes_details) - if changes_details == 'full': - _cs_json['refs'] = { - 'branches': [commit.branch], - 'bookmarks': getattr(commit, 'bookmarks', []), - 'tags': commit.tags + _cs_json["diff"] = build_commit_data(vcs_repo, commit, changes_details) + if changes_details == "full": + _cs_json["refs"] = { + "branches": [commit.branch], + "bookmarks": getattr(commit, "bookmarks", []), + "tags": commit.tags, } ret.append(_cs_json) return ret @jsonrpc_method() -def get_repo_nodes(request, apiuser, repoid, revision, root_path, - ret_type=Optional('all'), details=Optional('basic'), - max_file_bytes=Optional(None)): +def get_repo_nodes( + request, + apiuser, + repoid, + revision, + root_path, + ret_type=Optional("all"), + details=Optional("basic"), + max_file_bytes=Optional(None), +): """ Returns a list of nodes and children in a flat list for a given path at given revision. @@ -462,24 +475,28 @@ def get_repo_nodes(request, apiuser, repoid, revision, root_path, repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write', 'repository.read',) + _perms = ( + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) ret_type = Optional.extract(ret_type) details = Optional.extract(details) max_file_bytes = Optional.extract(max_file_bytes) - _extended_types = ['basic', 'full'] + _extended_types = ["basic", "full"] if details not in _extended_types: - ret_types = ','.join(_extended_types) - raise JSONRPCError(f'ret_type must be one of {ret_types}') + ret_types = ",".join(_extended_types) + raise JSONRPCError(f"ret_type must be one of {ret_types}") extended_info = False content = False - if details == 'basic': + if details == "basic": extended_info = True - if details == 'full': + if details == "full": extended_info = content = True _map = {} @@ -490,29 +507,41 @@ def get_repo_nodes(request, apiuser, repoid, revision, root_path, return [] _d, _f = ScmModel().get_nodes( - repo, revision, root_path, flat=False, - extended_info=extended_info, content=content, - max_file_bytes=max_file_bytes) + repo, + revision, + root_path, + flat=False, + extended_info=extended_info, + content=content, + max_file_bytes=max_file_bytes, + ) _map = { - 'all': _d + _f, - 'files': _f, - 'dirs': _d, + "all": _d + _f, + "files": _f, + "dirs": _d, } return _map[ret_type] except KeyError: - keys = ','.join(sorted(_map.keys())) - raise JSONRPCError(f'ret_type must be one of {keys}') + keys = ",".join(sorted(_map.keys())) + raise JSONRPCError(f"ret_type must be one of {keys}") except Exception: log.exception("Exception occurred while trying to get repo nodes") - raise JSONRPCError(f'failed to get repo: `{repo.repo_name}` nodes') + raise JSONRPCError(f"failed to get repo: `{repo.repo_name}` nodes") @jsonrpc_method() -def get_repo_file(request, apiuser, repoid, commit_id, file_path, - max_file_bytes=Optional(0), details=Optional('basic'), - cache=Optional(True)): +def get_repo_file( + request, + apiuser, + repoid, + commit_id, + file_path, + max_file_bytes=Optional(0), + details=Optional("basic"), + cache=Optional(True), +): """ Returns a single file from repository at given revision. @@ -557,27 +586,31 @@ def get_repo_file(request, apiuser, repoid, commit_id, file_path, repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write', 'repository.read',) + _perms = ( + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) cache = Optional.extract(cache, binary=True) details = Optional.extract(details) max_file_bytes = Optional.extract(max_file_bytes) - _extended_types = ['minimal', 'minimal+search', 'basic', 'full'] + _extended_types = ["minimal", "minimal+search", "basic", "full"] if details not in _extended_types: - ret_types = ','.join(_extended_types) - raise JSONRPCError(f'ret_type must be one of %s, got {ret_types}', details) + ret_types = ",".join(_extended_types) + raise JSONRPCError(f"ret_type must be one of %s, got {ret_types}", details) extended_info = False content = False - if details == 'minimal': + if details == "minimal": extended_info = False - elif details == 'basic': + elif details == "basic": extended_info = True - elif details == 'full': + elif details == "full": extended_info = content = True file_path = safe_str(file_path) @@ -588,16 +621,22 @@ def get_repo_file(request, apiuser, repoid, commit_id, file_path, return None node = ScmModel().get_node( - repo, commit_id, file_path, extended_info=extended_info, - content=content, max_file_bytes=max_file_bytes, cache=cache) + repo, + commit_id, + file_path, + extended_info=extended_info, + content=content, + max_file_bytes=max_file_bytes, + cache=cache, + ) except NodeDoesNotExistError: raise JSONRPCError( - f'There is no file in repo: `{repo.repo_name}` at path `{file_path}` for commit: `{commit_id}`') + f"There is no file in repo: `{repo.repo_name}` at path `{file_path}` for commit: `{commit_id}`" + ) except Exception: - log.exception("Exception occurred while trying to get repo %s file", - repo.repo_name) - raise JSONRPCError(f'failed to get repo: `{repo.repo_name}` file at path {file_path}') + log.exception("Exception occurred while trying to get repo %s file", repo.repo_name) + raise JSONRPCError(f"failed to get repo: `{repo.repo_name}` file at path {file_path}") return node @@ -615,15 +654,19 @@ def get_repo_fts_tree(request, apiuser, repoid, commit_id, root_path): repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write', 'repository.read',) + _perms = ( + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) repo_id = repo.repo_id - cache_seconds = rhodecode.ConfigGet().get_int('rc_cache.cache_repo.expiration_time') + cache_seconds = rhodecode.ConfigGet().get_int("rc_cache.cache_repo.expiration_time") cache_on = cache_seconds > 0 - cache_namespace_uid = f'repo.{rc_cache.FILE_TREE_CACHE_VER}.{repo_id}' - rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) + cache_namespace_uid = f"repo.{rc_cache.FILE_TREE_CACHE_VER}.{repo_id}" + rc_cache.get_or_create_region("cache_repo", cache_namespace_uid) def compute_fts_tree(repo_id, commit_id, root_path): return ScmModel().get_fts_data(repo_id, commit_id, root_path) @@ -635,16 +678,16 @@ def get_repo_fts_tree(request, apiuser, repoid, commit_id, root_path): return [] except RepositoryError: log.exception("Exception occurred while trying to get repo nodes") - raise JSONRPCError(f'failed to get repo: `{repo.repo_name}` nodes') + raise JSONRPCError(f"failed to get repo: `{repo.repo_name}` nodes") try: # we need to resolve commit_id to a FULL sha for cache to work correctly. # sending 'master' is a pointer that needs to be translated to current commit. commit_id = _scm.get_commit(commit_id=commit_id).raw_id log.debug( - 'Computing FTS REPO TREE for repo_id %s commit_id `%s` ' - 'with caching: %s[TTL: %ss]' % ( - repo_id, commit_id, cache_on, cache_seconds or 0)) + "Computing FTS REPO TREE for repo_id %s commit_id `%s` " + "with caching: %s[TTL: %ss]" % (repo_id, commit_id, cache_on, cache_seconds or 0) + ) tree_files = compute_fts_tree(repo_id, commit_id, root_path) @@ -652,7 +695,7 @@ def get_repo_fts_tree(request, apiuser, repoid, commit_id, root_path): except Exception: log.exception("Exception occurred while trying to get repo nodes") - raise JSONRPCError('failed to get repo: `%s` nodes' % repo.repo_name) + raise JSONRPCError("failed to get repo: `%s` nodes" % repo.repo_name) @jsonrpc_method() @@ -698,7 +741,11 @@ def get_repo_refs(request, apiuser, repoid): repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write', 'repository.read',) + _perms = ( + "repository.admin", + "repository.write", + "repository.read", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) try: @@ -708,24 +755,26 @@ def get_repo_refs(request, apiuser, repoid): return refs except Exception: log.exception("Exception occurred while trying to get repo refs") - raise JSONRPCError( - 'failed to get repo: `%s` references' % repo.repo_name - ) + raise JSONRPCError("failed to get repo: `%s` references" % repo.repo_name) @jsonrpc_method() def create_repo( - request, apiuser, repo_name, repo_type, - owner=Optional(OAttr('apiuser')), - description=Optional(''), - private=Optional(False), - clone_uri=Optional(None), - push_uri=Optional(None), - landing_rev=Optional(None), - enable_statistics=Optional(False), - enable_locking=Optional(False), - enable_downloads=Optional(False), - copy_permissions=Optional(False)): + request, + apiuser, + repo_name, + repo_type, + owner=Optional(OAttr("apiuser")), + description=Optional(""), + private=Optional(False), + clone_uri=Optional(None), + push_uri=Optional(None), + landing_rev=Optional(None), + enable_statistics=Optional(False), + enable_locking=Optional(False), + enable_downloads=Optional(False), + copy_permissions=Optional(False), +): """ Creates a repository. @@ -803,15 +852,15 @@ def create_repo( defs = SettingsModel().get_default_repo_settings(strip_prefix=True) if isinstance(private, Optional): - private = defs.get('repo_private') or Optional.extract(private) + private = defs.get("repo_private") or Optional.extract(private) if isinstance(repo_type, Optional): - repo_type = defs.get('repo_type') + repo_type = defs.get("repo_type") if isinstance(enable_statistics, Optional): - enable_statistics = defs.get('repo_enable_statistics') + enable_statistics = defs.get("repo_enable_statistics") if isinstance(enable_locking, Optional): - enable_locking = defs.get('repo_enable_locking') + enable_locking = defs.get("repo_enable_locking") if isinstance(enable_downloads, Optional): - enable_downloads = defs.get('repo_enable_downloads') + enable_downloads = defs.get("repo_enable_downloads") landing_ref, _label = ScmModel.backend_landing_ref(repo_type) ref_choices, _labels = ScmModel().get_repo_landing_revs(request.translate) @@ -824,63 +873,63 @@ def create_repo( repo_ref_options=ref_choices, repo_type=repo_type, # user caller - user=apiuser) + user=apiuser, + ) try: - schema_data = schema.deserialize(dict( - repo_name=repo_name, - repo_type=repo_type, - repo_owner=owner.username, - repo_description=description, - repo_landing_commit_ref=landing_commit_ref, - repo_clone_uri=clone_uri, - repo_push_uri=push_uri, - repo_private=private, - repo_copy_permissions=copy_permissions, - repo_enable_statistics=enable_statistics, - repo_enable_downloads=enable_downloads, - repo_enable_locking=enable_locking)) + schema_data = schema.deserialize( + dict( + repo_name=repo_name, + repo_type=repo_type, + repo_owner=owner.username, + repo_description=description, + repo_landing_commit_ref=landing_commit_ref, + repo_clone_uri=clone_uri, + repo_push_uri=push_uri, + repo_private=private, + repo_copy_permissions=copy_permissions, + repo_enable_statistics=enable_statistics, + repo_enable_downloads=enable_downloads, + repo_enable_locking=enable_locking, + ) + ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) try: data = { - 'owner': owner, - 'repo_name': schema_data['repo_group']['repo_name_without_group'], - 'repo_name_full': schema_data['repo_name'], - 'repo_group': schema_data['repo_group']['repo_group_id'], - 'repo_type': schema_data['repo_type'], - 'repo_description': schema_data['repo_description'], - 'repo_private': schema_data['repo_private'], - 'clone_uri': schema_data['repo_clone_uri'], - 'push_uri': schema_data['repo_push_uri'], - 'repo_landing_rev': schema_data['repo_landing_commit_ref'], - 'enable_statistics': schema_data['repo_enable_statistics'], - 'enable_locking': schema_data['repo_enable_locking'], - 'enable_downloads': schema_data['repo_enable_downloads'], - 'repo_copy_permissions': schema_data['repo_copy_permissions'], + "owner": owner, + "repo_name": schema_data["repo_group"]["repo_name_without_group"], + "repo_name_full": schema_data["repo_name"], + "repo_group": schema_data["repo_group"]["repo_group_id"], + "repo_type": schema_data["repo_type"], + "repo_description": schema_data["repo_description"], + "repo_private": schema_data["repo_private"], + "clone_uri": schema_data["repo_clone_uri"], + "push_uri": schema_data["repo_push_uri"], + "repo_landing_rev": schema_data["repo_landing_commit_ref"], + "enable_statistics": schema_data["repo_enable_statistics"], + "enable_locking": schema_data["repo_enable_locking"], + "enable_downloads": schema_data["repo_enable_downloads"], + "repo_copy_permissions": schema_data["repo_copy_permissions"], } task = RepoModel().create(form_data=data, cur_user=owner.user_id) task_id = get_task_id(task) # no commit, it's done in RepoModel, or async via celery return { - 'msg': "Created new repository `{}`".format(schema_data['repo_name']), - 'success': True, # cannot return the repo data here since fork + "msg": "Created new repository `{}`".format(schema_data["repo_name"]), + "success": True, # cannot return the repo data here since fork # can be done async - 'task': task_id + "task": task_id, } except Exception: - log.exception( - "Exception while trying to create the repository %s", - schema_data['repo_name']) - raise JSONRPCError( - 'failed to create repository `{}`'.format(schema_data['repo_name'])) + log.exception("Exception while trying to create the repository %s", schema_data["repo_name"]) + raise JSONRPCError("failed to create repository `{}`".format(schema_data["repo_name"])) @jsonrpc_method() -def add_field_to_repo(request, apiuser, repoid, key, label=Optional(''), - description=Optional('')): +def add_field_to_repo(request, apiuser, repoid, key, label=Optional(""), description=Optional("")): """ Adds an extra field to a repository. @@ -900,7 +949,7 @@ def add_field_to_repo(request, apiuser, repoid, key, label=Optional(''), """ repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) label = Optional.extract(label) or key @@ -908,20 +957,18 @@ def add_field_to_repo(request, apiuser, repoid, key, label=Optional(''), field = RepositoryField.get_by_key_name(key, repo) if field: - raise JSONRPCError(f'Field with key `{key}` exists for repo `{repoid}`') + raise JSONRPCError(f"Field with key `{key}` exists for repo `{repoid}`") try: - RepoModel().add_repo_field(repo, key, field_label=label, - field_desc=description) + RepoModel().add_repo_field(repo, key, field_label=label, field_desc=description) Session().commit() return { - 'msg': f"Added new repository field `{key}`", - 'success': True, + "msg": f"Added new repository field `{key}`", + "success": True, } except Exception: log.exception("Exception occurred while trying to add field to repo") - raise JSONRPCError( - f'failed to create new field for repository `{repoid}`') + raise JSONRPCError(f"failed to create new field for repository `{repoid}`") @jsonrpc_method() @@ -942,38 +989,43 @@ def remove_field_from_repo(request, apiuser, repoid, key): repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) field = RepositoryField.get_by_key_name(key, repo) if not field: - raise JSONRPCError('Field with key `%s` does not ' - 'exists for repo `%s`' % (key, repoid)) + raise JSONRPCError("Field with key `%s` does not exists for repo `%s`" % (key, repoid)) try: RepoModel().delete_repo_field(repo, field_key=key) Session().commit() return { - 'msg': f"Deleted repository field `{key}`", - 'success': True, + "msg": f"Deleted repository field `{key}`", + "success": True, } except Exception: - log.exception( - "Exception occurred while trying to delete field from repo") - raise JSONRPCError( - f'failed to delete field for repository `{repoid}`') + log.exception("Exception occurred while trying to delete field from repo") + raise JSONRPCError(f"failed to delete field for repository `{repoid}`") @jsonrpc_method() def update_repo( - request, apiuser, repoid, repo_name=Optional(None), - owner=Optional(OAttr('apiuser')), description=Optional(''), - private=Optional(False), - clone_uri=Optional(None), push_uri=Optional(None), - landing_rev=Optional(None), fork_of=Optional(None), - enable_statistics=Optional(False), - enable_locking=Optional(False), - enable_downloads=Optional(False), fields=Optional('')): + request, + apiuser, + repoid, + repo_name=Optional(None), + owner=Optional(OAttr("apiuser")), + description=Optional(""), + private=Optional(False), + clone_uri=Optional(None), + push_uri=Optional(None), + landing_rev=Optional(None), + fork_of=Optional(None), + enable_statistics=Optional(False), + enable_locking=Optional(False), + enable_downloads=Optional(False), + fields=Optional(""), +): r""" Updates a repository with the given information. @@ -1023,48 +1075,29 @@ def update_repo( include_secrets = False if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) else: include_secrets = True updates = dict( - repo_name=repo_name - if not isinstance(repo_name, Optional) else repo.repo_name, - - fork_id=fork_of - if not isinstance(fork_of, Optional) else repo.fork.repo_name if repo.fork else None, - - user=owner - if not isinstance(owner, Optional) else repo.user.username, - - repo_description=description - if not isinstance(description, Optional) else repo.description, - - repo_private=private - if not isinstance(private, Optional) else repo.private, - - clone_uri=clone_uri - if not isinstance(clone_uri, Optional) else repo.clone_uri, - - push_uri=push_uri - if not isinstance(push_uri, Optional) else repo.push_uri, - - repo_landing_rev=landing_rev - if not isinstance(landing_rev, Optional) else repo._landing_revision, - + repo_name=repo_name if not isinstance(repo_name, Optional) else repo.repo_name, + fork_id=fork_of if not isinstance(fork_of, Optional) else repo.fork.repo_name if repo.fork else None, + user=owner if not isinstance(owner, Optional) else repo.user.username, + repo_description=description if not isinstance(description, Optional) else repo.description, + repo_private=private if not isinstance(private, Optional) else repo.private, + clone_uri=clone_uri if not isinstance(clone_uri, Optional) else repo.clone_uri, + push_uri=push_uri if not isinstance(push_uri, Optional) else repo.push_uri, + repo_landing_rev=landing_rev if not isinstance(landing_rev, Optional) else repo._landing_revision, repo_enable_statistics=enable_statistics - if not isinstance(enable_statistics, Optional) else repo.enable_statistics, - - repo_enable_locking=enable_locking - if not isinstance(enable_locking, Optional) else repo.enable_locking, - - repo_enable_downloads=enable_downloads - if not isinstance(enable_downloads, Optional) else repo.enable_downloads) + if not isinstance(enable_statistics, Optional) + else repo.enable_statistics, + repo_enable_locking=enable_locking if not isinstance(enable_locking, Optional) else repo.enable_locking, + repo_enable_downloads=enable_downloads if not isinstance(enable_downloads, Optional) else repo.enable_downloads, + ) landing_ref, _label = ScmModel.backend_landing_ref(repo.repo_type) - ref_choices, _labels = ScmModel().get_repo_landing_revs( - request.translate, repo=repo) + ref_choices, _labels = ScmModel().get_repo_landing_revs(request.translate, repo=repo) ref_choices = list(set(ref_choices + [landing_ref])) old_values = repo.get_api_data() @@ -1075,76 +1108,79 @@ def update_repo( repo_type=repo_type, # user caller user=apiuser, - old_values=old_values) + old_values=old_values, + ) try: - schema_data = schema.deserialize(dict( - # we save old value, users cannot change type - repo_type=repo_type, - - repo_name=updates['repo_name'], - repo_owner=updates['user'], - repo_description=updates['repo_description'], - repo_clone_uri=updates['clone_uri'], - repo_push_uri=updates['push_uri'], - repo_fork_of=updates['fork_id'], - repo_private=updates['repo_private'], - repo_landing_commit_ref=updates['repo_landing_rev'], - repo_enable_statistics=updates['repo_enable_statistics'], - repo_enable_downloads=updates['repo_enable_downloads'], - repo_enable_locking=updates['repo_enable_locking'])) + schema_data = schema.deserialize( + dict( + # we save old value, users cannot change type + repo_type=repo_type, + repo_name=updates["repo_name"], + repo_owner=updates["user"], + repo_description=updates["repo_description"], + repo_clone_uri=updates["clone_uri"], + repo_push_uri=updates["push_uri"], + repo_fork_of=updates["fork_id"], + repo_private=updates["repo_private"], + repo_landing_commit_ref=updates["repo_landing_rev"], + repo_enable_statistics=updates["repo_enable_statistics"], + repo_enable_downloads=updates["repo_enable_downloads"], + repo_enable_locking=updates["repo_enable_locking"], + ) + ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) # save validated data back into the updates dict validated_updates = dict( - repo_name=schema_data['repo_group']['repo_name_without_group'], - repo_group=schema_data['repo_group']['repo_group_id'], - - user=schema_data['repo_owner'], - repo_description=schema_data['repo_description'], - repo_private=schema_data['repo_private'], - clone_uri=schema_data['repo_clone_uri'], - push_uri=schema_data['repo_push_uri'], - repo_landing_rev=schema_data['repo_landing_commit_ref'], - repo_enable_statistics=schema_data['repo_enable_statistics'], - repo_enable_locking=schema_data['repo_enable_locking'], - repo_enable_downloads=schema_data['repo_enable_downloads'], + repo_name=schema_data["repo_group"]["repo_name_without_group"], + repo_group=schema_data["repo_group"]["repo_group_id"], + user=schema_data["repo_owner"], + repo_description=schema_data["repo_description"], + repo_private=schema_data["repo_private"], + clone_uri=schema_data["repo_clone_uri"], + push_uri=schema_data["repo_push_uri"], + repo_landing_rev=schema_data["repo_landing_commit_ref"], + repo_enable_statistics=schema_data["repo_enable_statistics"], + repo_enable_locking=schema_data["repo_enable_locking"], + repo_enable_downloads=schema_data["repo_enable_downloads"], ) - if schema_data['repo_fork_of']: - fork_repo = get_repo_or_error(schema_data['repo_fork_of']) - validated_updates['fork_id'] = fork_repo.repo_id + if schema_data["repo_fork_of"]: + fork_repo = get_repo_or_error(schema_data["repo_fork_of"]) + validated_updates["fork_id"] = fork_repo.repo_id # extra fields - fields = parse_args(Optional.extract(fields), key_prefix='ex_') + fields = parse_args(Optional.extract(fields), key_prefix="ex_") if fields: validated_updates.update(fields) try: RepoModel().update(repo, **validated_updates) - audit_logger.store_api( - 'repo.edit', action_data={'old_data': old_values}, - user=apiuser, repo=repo) + audit_logger.store_api("repo.edit", action_data={"old_data": old_values}, user=apiuser, repo=repo) Session().commit() return { - 'msg': f'updated repo ID:{repo.repo_id} {repo.repo_name}', - 'repository': repo.get_api_data(include_secrets=include_secrets) + "msg": f"updated repo ID:{repo.repo_id} {repo.repo_name}", + "repository": repo.get_api_data(include_secrets=include_secrets), } except Exception: - log.exception( - "Exception while trying to update the repository %s", - repoid) - raise JSONRPCError('failed to update repo `%s`' % repoid) + log.exception("Exception while trying to update the repository %s", repoid) + raise JSONRPCError("failed to update repo `%s`" % repoid) @jsonrpc_method() -def fork_repo(request, apiuser, repoid, fork_name, - owner=Optional(OAttr('apiuser')), - description=Optional(''), - private=Optional(False), - clone_uri=Optional(None), - landing_rev=Optional(None), - copy_permissions=Optional(False)): +def fork_repo( + request, + apiuser, + repoid, + fork_name, + owner=Optional(OAttr("apiuser")), + description=Optional(""), + private=Optional(False), + clone_uri=Optional(None), + landing_rev=Optional(None), + copy_permissions=Optional(False), +): """ Creates a fork of the specified |repo|. @@ -1211,7 +1247,7 @@ def fork_repo(request, apiuser, repoid, fork_name, if not has_superadmin_permission(apiuser): # check if we have at least read permission for # this repo that we fork ! - _perms = ('repository.admin', 'repository.write', 'repository.read') + _perms = ("repository.admin", "repository.write", "repository.read") validate_repo_permissions(apiuser, repoid, repo, _perms) # check if the regular user has at least fork permissions as well @@ -1237,33 +1273,36 @@ def fork_repo(request, apiuser, repoid, fork_name, repo_ref_options=ref_choices, repo_type=repo.repo_type, # user caller - user=apiuser) + user=apiuser, + ) try: - schema_data = schema.deserialize(dict( - repo_name=fork_name, - repo_type=repo.repo_type, - repo_owner=owner.username, - repo_description=description, - repo_landing_commit_ref=landing_commit_ref, - repo_clone_uri=clone_uri, - repo_private=private, - repo_copy_permissions=copy_permissions)) + schema_data = schema.deserialize( + dict( + repo_name=fork_name, + repo_type=repo.repo_type, + repo_owner=owner.username, + repo_description=description, + repo_landing_commit_ref=landing_commit_ref, + repo_clone_uri=clone_uri, + repo_private=private, + repo_copy_permissions=copy_permissions, + ) + ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) try: data = { - 'fork_parent_id': repo.repo_id, - - 'repo_name': schema_data['repo_group']['repo_name_without_group'], - 'repo_name_full': schema_data['repo_name'], - 'repo_group': schema_data['repo_group']['repo_group_id'], - 'repo_type': schema_data['repo_type'], - 'description': schema_data['repo_description'], - 'private': schema_data['repo_private'], - 'copy_permissions': schema_data['repo_copy_permissions'], - 'landing_rev': schema_data['repo_landing_commit_ref'], + "fork_parent_id": repo.repo_id, + "repo_name": schema_data["repo_group"]["repo_name_without_group"], + "repo_name_full": schema_data["repo_name"], + "repo_group": schema_data["repo_group"]["repo_group_id"], + "repo_type": schema_data["repo_type"], + "description": schema_data["repo_description"], + "private": schema_data["repo_private"], + "copy_permissions": schema_data["repo_copy_permissions"], + "landing_rev": schema_data["repo_landing_commit_ref"], } task = RepoModel().create_fork(data, cur_user=owner.user_id) @@ -1271,23 +1310,18 @@ def fork_repo(request, apiuser, repoid, fork_name, task_id = get_task_id(task) return { - 'msg': 'Created fork of `{}` as `{}`'.format( - repo.repo_name, schema_data['repo_name']), - 'success': True, # cannot return the repo data here since fork + "msg": "Created fork of `{}` as `{}`".format(repo.repo_name, schema_data["repo_name"]), + "success": True, # cannot return the repo data here since fork # can be done async - 'task': task_id + "task": task_id, } except Exception: - log.exception( - "Exception while trying to create fork %s", - schema_data['repo_name']) - raise JSONRPCError( - 'failed to fork repository `{}` as `{}`'.format( - repo_name, schema_data['repo_name'])) + log.exception("Exception while trying to create fork %s", schema_data["repo_name"]) + raise JSONRPCError("failed to fork repository `{}` as `{}`".format(repo_name, schema_data["repo_name"])) @jsonrpc_method() -def delete_repo(request, apiuser, repoid, forks=Optional('')): +def delete_repo(request, apiuser, repoid, forks=Optional("")): """ Deletes a repository. @@ -1319,46 +1353,35 @@ def delete_repo(request, apiuser, repoid, forks=Optional('')): repo = get_repo_or_error(repoid) repo_name = repo.repo_name if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) try: handle_forks = Optional.extract(forks) - _forks_msg = '' + _forks_msg = "" _forks = [f for f in repo.forks] - if handle_forks == 'detach': - _forks_msg = ' ' + 'Detached %s forks' % len(_forks) - elif handle_forks == 'delete': - _forks_msg = ' ' + 'Deleted %s forks' % len(_forks) + if handle_forks == "detach": + _forks_msg = " " + "Detached %s forks" % len(_forks) + elif handle_forks == "delete": + _forks_msg = " " + "Deleted %s forks" % len(_forks) elif _forks: - raise JSONRPCError( - 'Cannot delete `%s` it still contains attached forks' % - (repo.repo_name,) - ) + raise JSONRPCError("Cannot delete `%s` it still contains attached forks" % (repo.repo_name,)) old_data = repo.get_api_data() RepoModel().delete(repo, forks=forks) - repo = audit_logger.RepoWrap(repo_id=None, - repo_name=repo.repo_name) + repo = audit_logger.RepoWrap(repo_id=None, repo_name=repo.repo_name) - audit_logger.store_api( - 'repo.delete', action_data={'old_data': old_data}, - user=apiuser, repo=repo) + audit_logger.store_api("repo.delete", action_data={"old_data": old_data}, user=apiuser, repo=repo) ScmModel().mark_for_invalidation(repo_name, delete=True) Session().commit() - return { - 'msg': f'Deleted repository `{repo_name}`{_forks_msg}', - 'success': True - } + return {"msg": f"Deleted repository `{repo_name}`{_forks_msg}", "success": True} except Exception: log.exception("Exception occurred while trying to delete repo") - raise JSONRPCError( - f'failed to delete repository `{repo_name}`' - ) + raise JSONRPCError(f"failed to delete repository `{repo_name}`") -#TODO: marcink, change name ? +# TODO: marcink, change name ? @jsonrpc_method() def invalidate_cache(request, apiuser, repoid, delete_keys=Optional(False)): """ @@ -1402,28 +1425,24 @@ def invalidate_cache(request, apiuser, repoid, delete_keys=Optional(False)): repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin', 'repository.write',) + _perms = ( + "repository.admin", + "repository.write", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) delete = Optional.extract(delete_keys) try: ScmModel().mark_for_invalidation(repo.repo_name, delete=delete) - return { - 'msg': f'Cache for repository `{repoid}` was invalidated', - 'repository': repo.repo_name - } + return {"msg": f"Cache for repository `{repoid}` was invalidated", "repository": repo.repo_name} except Exception: - log.exception( - "Exception occurred while trying to invalidate repo cache") - raise JSONRPCError( - 'Error occurred during cache invalidation action' - ) + log.exception("Exception occurred while trying to invalidate repo cache") + raise JSONRPCError("Error occurred during cache invalidation action") -#TODO: marcink, change name ? +# TODO: marcink, change name ? @jsonrpc_method() -def lock(request, apiuser, repoid, locked=Optional(None), - userid=Optional(OAttr('apiuser'))): +def lock(request, apiuser, repoid, locked=Optional(None), userid=Optional(OAttr("apiuser"))): """ Sets the lock state of the specified |repo| by the given user. From more information, see :ref:`repo-locking`. @@ -1481,13 +1500,16 @@ def lock(request, apiuser, repoid, locked=Optional(None), repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): # check if we have at least write permission for this repo ! - _perms = ('repository.admin', 'repository.write',) + _perms = ( + "repository.admin", + "repository.write", + ) validate_repo_permissions(apiuser, repoid, repo, _perms) # make sure normal user does not pass someone else userid, # he is not allowed to do that if not isinstance(userid, Optional) and userid != apiuser.user_id: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") if isinstance(userid, Optional): userid = apiuser.user_id @@ -1499,28 +1521,29 @@ def lock(request, apiuser, repoid, locked=Optional(None), if lockobj[0] is None: _d = { - 'repo': repo.repo_name, - 'locked': False, - 'locked_since': None, - 'locked_by': None, - 'lock_reason': None, - 'lock_state_changed': False, - 'msg': 'Repo `%s` not locked.' % repo.repo_name + "repo": repo.repo_name, + "locked": False, + "locked_since": None, + "locked_by": None, + "lock_reason": None, + "lock_state_changed": False, + "msg": "Repo `%s` not locked." % repo.repo_name, } return _d else: _user_id, _time, _reason = lockobj lock_user = get_user_or_error(userid) _d = { - 'repo': repo.repo_name, - 'locked': True, - 'locked_since': _time, - 'locked_by': lock_user.username, - 'lock_reason': _reason, - 'lock_state_changed': False, - 'msg': ('Repo `%s` locked by `%s` on `%s`.' - % (repo.repo_name, lock_user.username, - json.dumps(time_to_datetime(_time)))) + "repo": repo.repo_name, + "locked": True, + "locked_since": _time, + "locked_by": lock_user.username, + "lock_reason": _reason, + "lock_state_changed": False, + "msg": ( + "Repo `%s` locked by `%s` on `%s`." + % (repo.repo_name, lock_user.username, json.dumps(time_to_datetime(_time))) + ), } return _d @@ -1536,30 +1559,34 @@ def lock(request, apiuser, repoid, locked=Optional(None), lock_time = None Repository.unlock(repo) _d = { - 'repo': repo.repo_name, - 'locked': locked, - 'locked_since': lock_time, - 'locked_by': user.username, - 'lock_reason': lock_reason, - 'lock_state_changed': True, - 'msg': ('User `%s` set lock state for repo `%s` to `%s`' - % (user.username, repo.repo_name, locked)) + "repo": repo.repo_name, + "locked": locked, + "locked_since": lock_time, + "locked_by": user.username, + "lock_reason": lock_reason, + "lock_state_changed": True, + "msg": ("User `%s` set lock state for repo `%s` to `%s`" % (user.username, repo.repo_name, locked)), } return _d except Exception: - log.exception( - "Exception occurred while trying to lock repository") - raise JSONRPCError( - 'Error occurred locking repository `%s`' % repo.repo_name - ) + log.exception("Exception occurred while trying to lock repository") + raise JSONRPCError("Error occurred locking repository `%s`" % repo.repo_name) @jsonrpc_method() def comment_commit( - request, apiuser, repoid, commit_id, message, status=Optional(None), - comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), - resolves_comment_id=Optional(None), extra_recipients=Optional([]), - userid=Optional(OAttr('apiuser')), send_email=Optional(True)): + request, + apiuser, + repoid, + commit_id, + message, + status=Optional(None), + comment_type=Optional(ChangesetComment.COMMENT_TYPE_NOTE), + resolves_comment_id=Optional(None), + extra_recipients=Optional([]), + userid=Optional(OAttr("apiuser")), + send_email=Optional(True), +): """ Set a commit comment, and optionally change the status of the commit. @@ -1605,7 +1632,7 @@ def comment_commit( repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.read', 'repository.write', 'repository.admin') + _perms = ("repository.read", "repository.write", "repository.admin") validate_repo_permissions(apiuser, repoid, repo, _perms) db_repo_name = repo.repo_name @@ -1613,7 +1640,7 @@ def comment_commit( commit = repo.scm_instance().get_commit(commit_id=commit_id) commit_id = commit.raw_id except Exception as e: - log.exception('Failed to fetch commit') + log.exception("Failed to fetch commit") raise JSONRPCError(safe_str(e)) if isinstance(userid, Optional): @@ -1628,26 +1655,31 @@ def comment_commit( allowed_statuses = [x[0] for x in ChangesetStatus.STATUSES] if status and status not in allowed_statuses: - raise JSONRPCError('Bad status, must be on ' - 'of %s got %s' % (allowed_statuses, status,)) + raise JSONRPCError( + "Bad status, must be on " + "of %s got %s" + % ( + allowed_statuses, + status, + ) + ) if resolves_comment_id: comment = ChangesetComment.get(resolves_comment_id) if not comment: - raise JSONRPCError( - 'Invalid resolves_comment_id `%s` for this commit.' - % resolves_comment_id) + raise JSONRPCError("Invalid resolves_comment_id `%s` for this commit." % resolves_comment_id) if comment.comment_type != ChangesetComment.COMMENT_TYPE_TODO: - raise JSONRPCError( - 'Comment `%s` is wrong type for setting status to resolved.' - % resolves_comment_id) + raise JSONRPCError("Comment `%s` is wrong type for setting status to resolved." % resolves_comment_id) try: rc_config = SettingsModel().get_all_settings() - renderer = rc_config.get('rhodecode_markup_renderer', 'rst') + renderer = rc_config.get("rhodecode_markup_renderer", "rst") status_change_label = ChangesetStatus.get_status_lbl(status) comment = CommentsModel().create( - message, repo, user, commit_id=commit_id, + message, + repo, + user, + commit_id=commit_id, status_change=status_change_label, status_change_type=status, renderer=renderer, @@ -1655,7 +1687,7 @@ def comment_commit( resolves_comment_id=resolves_comment_id, auth_user=apiuser, extra_recipients=extra_recipients, - send_email=send_email + send_email=send_email, ) is_inline = comment.is_inline @@ -1663,38 +1695,35 @@ def comment_commit( # also do a status change try: ChangesetStatusModel().set_status( - repo, status, user, comment, revision=commit_id, - dont_allow_on_closed_pull_request=True + repo, status, user, comment, revision=commit_id, dont_allow_on_closed_pull_request=True ) except StatusChangeOnClosedPullRequestError: - log.exception( - "Exception occurred while trying to change repo commit status") - msg = ('Changing status on a commit associated with ' - 'a closed pull request is not allowed') + log.exception("Exception occurred while trying to change repo commit status") + msg = "Changing status on a commit associated with a closed pull request is not allowed" raise JSONRPCError(msg) CommentsModel().trigger_commit_comment_hook( - repo, apiuser, 'create', - data={'comment': comment, 'commit': commit}) + repo, apiuser, "create", data={"comment": comment, "commit": commit} + ) Session().commit() - comment_broadcast_channel = channelstream.comment_channel( - db_repo_name, commit_obj=commit) + comment_broadcast_channel = channelstream.comment_channel(db_repo_name, commit_obj=commit) - comment_data = {'comment': comment, 'comment_id': comment.comment_id} - comment_type = 'inline' if is_inline else 'general' + comment_data = {"comment": comment, "comment_id": comment.comment_id} + comment_type = "inline" if is_inline else "general" channelstream.comment_channelstream_push( - request, comment_broadcast_channel, apiuser, - _('posted a new {} comment').format(comment_type), - comment_data=comment_data) + request, + comment_broadcast_channel, + apiuser, + _("posted a new {} comment").format(comment_type), + comment_data=comment_data, + ) return { - 'msg': ( - 'Commented on commit `{}` for repository `{}`'.format( - comment.revision, repo.repo_name)), - 'status_change': status, - 'success': True, + "msg": ("Commented on commit `{}` for repository `{}`".format(comment.revision, repo.repo_name)), + "status_change": status, + "success": True, } except JSONRPCError: # catch any inside errors, and re-raise them to prevent from @@ -1702,15 +1731,13 @@ def comment_commit( raise except Exception: log.exception("Exception occurred while trying to comment on commit") - raise JSONRPCError( - f'failed to set comment on repository `{repo.repo_name}`' - ) + raise JSONRPCError(f"failed to set comment on repository `{repo.repo_name}`") @jsonrpc_method() -def get_repo_comments(request, apiuser, repoid, - commit_id=Optional(None), comment_type=Optional(None), - userid=Optional(None)): +def get_repo_comments( + request, apiuser, repoid, commit_id=Optional(None), comment_type=Optional(None), userid=Optional(None) +): """ Get all comments for a repository @@ -1752,7 +1779,7 @@ def get_repo_comments(request, apiuser, repoid, """ repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.read', 'repository.write', 'repository.admin') + _perms = ("repository.read", "repository.write", "repository.admin") validate_repo_permissions(apiuser, repoid, repo, _perms) commit_id = Optional.extract(commit_id) @@ -1766,12 +1793,12 @@ def get_repo_comments(request, apiuser, repoid, comment_type = Optional.extract(comment_type) if comment_type and comment_type not in ChangesetComment.COMMENT_TYPES: raise JSONRPCError( - 'comment_type must be one of `{}` got {}'.format( - ChangesetComment.COMMENT_TYPES, comment_type) - ) + "comment_type must be one of `{}` got {}".format(ChangesetComment.COMMENT_TYPES, comment_type) + ) comments = CommentsModel().get_repository_comments( - repo=repo, comment_type=comment_type, user=user, commit_id=commit_id) + repo=repo, comment_type=comment_type, user=user, commit_id=commit_id + ) return comments @@ -1810,21 +1837,19 @@ def get_comment(request, apiuser, comment_id): comment = ChangesetComment.get(comment_id) if not comment: - raise JSONRPCError(f'comment `{comment_id}` does not exist') + raise JSONRPCError(f"comment `{comment_id}` does not exist") - perms = ('repository.read', 'repository.write', 'repository.admin') - has_comment_perm = HasRepoPermissionAnyApi(*perms)\ - (user=apiuser, repo_name=comment.repo.repo_name) + perms = ("repository.read", "repository.write", "repository.admin") + has_comment_perm = HasRepoPermissionAnyApi(*perms)(user=apiuser, repo_name=comment.repo.repo_name) if not has_comment_perm: - raise JSONRPCError(f'comment `{comment_id}` does not exist') + raise JSONRPCError(f"comment `{comment_id}` does not exist") return comment @jsonrpc_method() -def edit_comment(request, apiuser, message, comment_id, version, - userid=Optional(OAttr('apiuser'))): +def edit_comment(request, apiuser, message, comment_id, version, userid=Optional(OAttr("apiuser"))): """ Edit comment on the pull request or commit, specified by the `comment_id` and version. Initially version should be 0 @@ -1855,18 +1880,17 @@ def edit_comment(request, apiuser, message, comment_id, version, auth_user = apiuser comment = ChangesetComment.get(comment_id) if not comment: - raise JSONRPCError(f'comment `{comment_id}` does not exist') + raise JSONRPCError(f"comment `{comment_id}` does not exist") is_super_admin = has_superadmin_permission(apiuser) - is_repo_admin = HasRepoPermissionAnyApi('repository.admin')\ - (user=apiuser, repo_name=comment.repo.repo_name) + is_repo_admin = HasRepoPermissionAnyApi("repository.admin")(user=apiuser, repo_name=comment.repo.repo_name) if not isinstance(userid, Optional): if is_super_admin or is_repo_admin: apiuser = get_user_or_error(userid) auth_user = apiuser.AuthUser() else: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") comment_author = comment.author.user_id == auth_user.user_id @@ -1885,30 +1909,24 @@ def edit_comment(request, apiuser, message, comment_id, version, ) Session().commit() except CommentVersionMismatch: - raise JSONRPCError( - f'comment ({comment_id}) version ({version}) mismatch' - ) + raise JSONRPCError(f"comment ({comment_id}) version ({version}) mismatch") if not comment_history and not message: - raise JSONRPCError( - f"comment ({comment_id}) can't be changed with empty string" - ) + raise JSONRPCError(f"comment ({comment_id}) can't be changed with empty string") if comment.pull_request: pull_request = comment.pull_request - PullRequestModel().trigger_pull_request_hook( - pull_request, apiuser, 'comment_edit', - data={'comment': comment}) + PullRequestModel().trigger_pull_request_hook(pull_request, apiuser, "comment_edit", data={"comment": comment}) else: db_repo = comment.repo commit_id = comment.revision commit = db_repo.get_commit(commit_id) CommentsModel().trigger_commit_comment_hook( - db_repo, apiuser, 'edit', - data={'comment': comment, 'commit': commit}) + db_repo, apiuser, "edit", data={"comment": comment, "commit": commit} + ) data = { - 'comment': comment, - 'version': comment_history.version if comment_history else None, + "comment": comment, + "version": comment_history.version if comment_history else None, } return data @@ -1930,6 +1948,7 @@ def edit_comment(request, apiuser, message, comment_id, version, # if not (comment.immutable is False and (is_super_admin or is_repo_admin) or comment_author): # raise JSONRPCError("you don't have access to edit this comment") + @jsonrpc_method() def grant_user_permission(request, apiuser, repoid, userid, perm): """ @@ -1965,37 +1984,31 @@ def grant_user_permission(request, apiuser, repoid, userid, perm): user = get_user_or_error(userid) perm = get_perm_or_error(perm) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) perm_additions = [[user.user_id, perm.permission_name, "user"]] try: - changes = RepoModel().update_permissions( - repo=repo, perm_additions=perm_additions, cur_user=apiuser) + changes = RepoModel().update_permissions(repo=repo, perm_additions=perm_additions, cur_user=apiuser) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + audit_logger.store_api("repo.edit.permissions", action_data=action_data, user=apiuser, repo=repo) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Granted perm: `{}` for user: `{}` in repo: `{}`'.format( + "msg": "Granted perm: `{}` for user: `{}` in repo: `{}`".format( perm.permission_name, user.username, repo.repo_name ), - 'success': True + "success": True, } except Exception: log.exception("Exception occurred while trying edit permissions for repo") - raise JSONRPCError( - 'failed to edit permission for user: `{}` in repo: `{}`'.format( - userid, repoid - ) - ) + raise JSONRPCError("failed to edit permission for user: `{}` in repo: `{}`".format(userid, repoid)) @jsonrpc_method() @@ -2028,37 +2041,29 @@ def revoke_user_permission(request, apiuser, repoid, userid): repo = get_repo_or_error(repoid) user = get_user_or_error(userid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) perm_deletions = [[user.user_id, None, "user"]] try: - changes = RepoModel().update_permissions( - repo=repo, perm_deletions=perm_deletions, cur_user=user) + changes = RepoModel().update_permissions(repo=repo, perm_deletions=perm_deletions, cur_user=user) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + audit_logger.store_api("repo.edit.permissions", action_data=action_data, user=apiuser, repo=repo) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Revoked perm for user: `{}` in repo: `{}`'.format( - user.username, repo.repo_name - ), - 'success': True + "msg": "Revoked perm for user: `{}` in repo: `{}`".format(user.username, repo.repo_name), + "success": True, } except Exception: log.exception("Exception occurred while trying revoke permissions to repo") - raise JSONRPCError( - 'failed to edit permission for user: `{}` in repo: `{}`'.format( - userid, repoid - ) - ) + raise JSONRPCError("failed to edit permission for user: `{}` in repo: `{}`".format(userid, repoid)) @jsonrpc_method() @@ -2107,48 +2112,41 @@ def grant_user_group_permission(request, apiuser, repoid, usergroupid, perm): repo = get_repo_or_error(repoid) perm = get_perm_or_error(perm) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): # check if we have at least read permission for this user group ! - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") perm_additions = [[user_group.users_group_id, perm.permission_name, "user_group"]] try: - changes = RepoModel().update_permissions( - repo=repo, perm_additions=perm_additions, cur_user=apiuser) + changes = RepoModel().update_permissions(repo=repo, perm_additions=perm_additions, cur_user=apiuser) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + audit_logger.store_api("repo.edit.permissions", action_data=action_data, user=apiuser, repo=repo) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Granted perm: `%s` for user group: `%s` in ' - 'repo: `%s`' % ( - perm.permission_name, user_group.users_group_name, - repo.repo_name - ), - 'success': True + "msg": "Granted perm: `%s` for user group: `%s` in " + "repo: `%s`" % (perm.permission_name, user_group.users_group_name, repo.repo_name), + "success": True, } except Exception: - log.exception( - "Exception occurred while trying change permission on repo") + log.exception("Exception occurred while trying change permission on repo") raise JSONRPCError( - 'failed to edit permission for user group: `%s` in ' - 'repo: `%s`' % ( - usergroupid, repo.repo_name - ) + "failed to edit permission for user group: `%s` in repo: `%s`" % (usergroupid, repo.repo_name) ) @@ -2181,46 +2179,43 @@ def revoke_user_group_permission(request, apiuser, repoid, usergroupid): repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): # check if we have at least read permission for this user group ! - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") perm_deletions = [[user_group.users_group_id, None, "user_group"]] try: - changes = RepoModel().update_permissions( - repo=repo, perm_deletions=perm_deletions, cur_user=apiuser) + changes = RepoModel().update_permissions(repo=repo, perm_deletions=perm_deletions, cur_user=apiuser) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo.edit.permissions', action_data=action_data, user=apiuser, repo=repo) + audit_logger.store_api("repo.edit.permissions", action_data=action_data, user=apiuser, repo=repo) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Revoked perm for user group: `{}` in repo: `{}`'.format( + "msg": "Revoked perm for user group: `{}` in repo: `{}`".format( user_group.users_group_name, repo.repo_name ), - 'success': True + "success": True, } except Exception: - log.exception("Exception occurred while trying revoke " - "user group permission on repo") + log.exception("Exception occurred while trying revoke user group permission on repo") raise JSONRPCError( - 'failed to edit permission for user group: `%s` in ' - 'repo: `%s`' % ( - user_group.users_group_name, repo.repo_name - ) + "failed to edit permission for user group: `%s` in " + "repo: `%s`" % (user_group.users_group_name, repo.repo_name) ) @@ -2273,23 +2268,20 @@ def pull(request, apiuser, repoid, remote_uri=Optional(None), sync_large_objects remote_uri_display = remote_uri or repo.clone_uri_hidden sync_large_objects = Optional.extract(sync_large_objects) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) try: ScmModel().pull_changes( - repo.repo_name, apiuser.username, remote_uri=remote_uri, sync_large_objects=sync_large_objects) + repo.repo_name, apiuser.username, remote_uri=remote_uri, sync_large_objects=sync_large_objects + ) return { - 'msg': 'Pulled from url `{}` on repo `{}`'.format( - remote_uri_display, repo.repo_name), - 'repository': repo.repo_name + "msg": "Pulled from url `{}` on repo `{}`".format(remote_uri_display, repo.repo_name), + "repository": repo.repo_name, } except Exception: - log.exception("Exception occurred while trying to " - "pull changes from remote location") - raise JSONRPCError( - 'Unable to pull changes from `%s`' % remote_uri_display - ) + log.exception("Exception occurred while trying to pull changes from remote location") + raise JSONRPCError("Unable to pull changes from `%s`" % remote_uri_display) @jsonrpc_method() @@ -2338,27 +2330,22 @@ def strip(request, apiuser, repoid, revision, branch): repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) try: ScmModel().strip(repo, revision, branch) audit_logger.store_api( - 'repo.commit.strip', action_data={'commit_id': revision}, - repo=repo, - user=apiuser, commit=True) + "repo.commit.strip", action_data={"commit_id": revision}, repo=repo, user=apiuser, commit=True + ) return { - 'msg': 'Stripped commit {} from repo `{}`'.format( - revision, repo.repo_name), - 'repository': repo.repo_name + "msg": "Stripped commit {} from repo `{}`".format(revision, repo.repo_name), + "repository": repo.repo_name, } except Exception: log.exception("Exception while trying to strip") - raise JSONRPCError( - 'Unable to strip commit {} from repo `{}`'.format( - revision, repo.repo_name) - ) + raise JSONRPCError("Unable to strip commit {} from repo `{}`".format(revision, repo.repo_name)) @jsonrpc_method() @@ -2398,7 +2385,7 @@ def get_repo_settings(request, apiuser, repoid, key=Optional(None)): # Restrict access to this api method to super-admins, and repo admins only. repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) try: @@ -2411,7 +2398,7 @@ def get_repo_settings(request, apiuser, repoid, key=Optional(None)): if key is not None: settings = settings.get(key, None) except Exception: - msg = f'Failed to fetch settings for repository `{repoid}`' + msg = f"Failed to fetch settings for repository `{repoid}`" log.exception(msg) raise JSONRPCError(msg) @@ -2443,11 +2430,11 @@ def set_repo_settings(request, apiuser, repoid, settings): # Restrict access to this api method to super-admins, and repo admins only. repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) if type(settings) is not dict: - raise JSONRPCError('Settings have to be a JSON Object.') + raise JSONRPCError("Settings have to be a JSON Object.") try: settings_model = VcsSettingsModel(repo=repoid) @@ -2458,13 +2445,11 @@ def set_repo_settings(request, apiuser, repoid, settings): new_settings.update(settings) # Update the settings. - inherit_global_settings = new_settings.get( - 'inherit_global_settings', False) - settings_model.create_or_update_repo_settings( - new_settings, inherit_global_settings=inherit_global_settings) + inherit_global_settings = new_settings.get("inherit_global_settings", False) + settings_model.create_or_update_repo_settings(new_settings, inherit_global_settings=inherit_global_settings) Session().commit() except Exception: - msg = f'Failed to update settings for repository `{repoid}`' + msg = f"Failed to update settings for repository `{repoid}`" log.exception(msg) raise JSONRPCError(msg) @@ -2516,7 +2501,7 @@ def maintenance(request, apiuser, repoid): repo = get_repo_or_error(repoid) if not has_superadmin_permission(apiuser): - _perms = ('repository.admin',) + _perms = ("repository.admin",) validate_repo_permissions(apiuser, repoid, repo, _perms) try: @@ -2524,11 +2509,10 @@ def maintenance(request, apiuser, repoid): executed_actions = maintenance.execute(repo) return { - 'msg': 'executed maintenance command', - 'executed_actions': executed_actions, - 'repository': repo.repo_name + "msg": "executed maintenance command", + "executed_actions": executed_actions, + "repository": repo.repo_name, } except Exception: log.exception("Exception occurred while trying to run maintenance") - raise JSONRPCError( - 'Unable to execute maintenance on `%s`' % repo.repo_name) + raise JSONRPCError("Unable to execute maintenance on `%s`" % repo.repo_name) diff --git a/rhodecode/api/views/repo_group_api.py b/rhodecode/api/views/repo_group_api.py index 53ddce53..f7c8d947 100644 --- a/rhodecode/api/views/repo_group_api.py +++ b/rhodecode/api/views/repo_group_api.py @@ -22,12 +22,19 @@ import logging from rhodecode.api import JSONRPCValidationError from rhodecode.api import jsonrpc_method, JSONRPCError from rhodecode.api.utils import ( - has_superadmin_permission, Optional, OAttr, get_user_or_error, - get_repo_group_or_error, get_perm_or_error, get_user_group_or_error, - get_origin, validate_repo_group_permissions, validate_set_owner_permissions) + has_superadmin_permission, + Optional, + OAttr, + get_user_or_error, + get_repo_group_or_error, + get_perm_or_error, + get_user_group_or_error, + get_origin, + validate_repo_group_permissions, + validate_set_owner_permissions, +) from rhodecode.lib import audit_logger -from rhodecode.lib.auth import ( - HasRepoGroupPermissionAnyApi, HasUserGroupPermissionAnyApi) +from rhodecode.lib.auth import HasRepoGroupPermissionAnyApi, HasUserGroupPermissionAnyApi from rhodecode.model.db import Session from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel @@ -92,28 +99,30 @@ def get_repo_group(request, apiuser, repogroupid): repo_group = get_repo_group_or_error(repogroupid) if not has_superadmin_permission(apiuser): # check if we have at least read permission for this repo group ! - _perms = ('group.admin', 'group.write', 'group.read',) - if not HasRepoGroupPermissionAnyApi(*_perms)( - user=apiuser, group_name=repo_group.group_name): - raise JSONRPCError( - f'repository group `{repogroupid}` does not exist') + _perms = ( + "group.admin", + "group.write", + "group.read", + ) + if not HasRepoGroupPermissionAnyApi(*_perms)(user=apiuser, group_name=repo_group.group_name): + raise JSONRPCError(f"repository group `{repogroupid}` does not exist") permissions = [] for _user in repo_group.permissions(): user_data = { - 'name': _user.username, - 'permission': _user.permission, - 'origin': get_origin(_user), - 'type': "user", + "name": _user.username, + "permission": _user.permission, + "origin": get_origin(_user), + "type": "user", } permissions.append(user_data) for _user_group in repo_group.permission_user_groups(): user_group_data = { - 'name': _user_group.users_group_name, - 'permission': _user_group.permission, - 'origin': get_origin(_user_group), - 'type': "user_group", + "name": _user_group.users_group_name, + "permission": _user_group.permission, + "origin": get_origin(_user_group), + "type": "user_group", } permissions.append(user_group_data) @@ -132,20 +141,26 @@ def get_repo_groups(request, apiuser): """ result = [] - _perms = ('group.read', 'group.write', 'group.admin',) - extras = {'user': apiuser} - for repo_group in RepoGroupList(RepoGroupModel().get_all(), - perm_set=_perms, extra_kwargs=extras): + _perms = ( + "group.read", + "group.write", + "group.admin", + ) + extras = {"user": apiuser} + for repo_group in RepoGroupList(RepoGroupModel().get_all(), perm_set=_perms, extra_kwargs=extras): result.append(repo_group.get_api_data()) return result @jsonrpc_method() def create_repo_group( - request, apiuser, group_name, - owner=Optional(OAttr('apiuser')), - description=Optional(''), - copy_permissions=Optional(False)): + request, + apiuser, + group_name, + owner=Optional(OAttr("apiuser")), + description=Optional(""), + copy_permissions=Optional(False), +): """ Creates a repository group. @@ -202,52 +217,55 @@ def create_repo_group( schema = repo_group_schema.RepoGroupSchema().bind( # user caller - user=apiuser) + user=apiuser + ) try: - schema_data = schema.deserialize(dict( - repo_group_name=group_name, - repo_group_owner=owner.username, - repo_group_description=description, - repo_group_copy_permissions=copy_permissions, - )) + schema_data = schema.deserialize( + dict( + repo_group_name=group_name, + repo_group_owner=owner.username, + repo_group_description=description, + repo_group_copy_permissions=copy_permissions, + ) + ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) - validated_group_name = schema_data['repo_group_name'] + validated_group_name = schema_data["repo_group_name"] try: repo_group = RepoGroupModel().create( owner=owner, group_name=validated_group_name, - group_description=schema_data['repo_group_description'], - copy_permissions=schema_data['repo_group_copy_permissions']) + group_description=schema_data["repo_group_description"], + copy_permissions=schema_data["repo_group_copy_permissions"], + ) Session().flush() repo_group_data = repo_group.get_api_data() - audit_logger.store_api( - 'repo_group.create', action_data={'data': repo_group_data}, - user=apiuser) + audit_logger.store_api("repo_group.create", action_data={"data": repo_group_data}, user=apiuser) Session().commit() PermissionModel().trigger_permission_flush() - return { - 'msg': 'Created new repo group `%s`' % validated_group_name, - 'repo_group': repo_group.get_api_data() - } + return {"msg": "Created new repo group `%s`" % validated_group_name, "repo_group": repo_group.get_api_data()} except Exception: log.exception("Exception occurred while trying create repo group") - raise JSONRPCError( - f'failed to create repo group `{validated_group_name}`') + raise JSONRPCError(f"failed to create repo group `{validated_group_name}`") @jsonrpc_method() def update_repo_group( - request, apiuser, repogroupid, group_name=Optional(''), - description=Optional(''), owner=Optional(OAttr('apiuser')), - enable_locking=Optional(False)): + request, + apiuser, + repogroupid, + group_name=Optional(""), + description=Optional(""), + owner=Optional(OAttr("apiuser")), + enable_locking=Optional(False), +): """ Updates repository group with the details given. @@ -280,65 +298,54 @@ def update_repo_group( repo_group = get_repo_group_or_error(repogroupid) if not has_superadmin_permission(apiuser): - validate_repo_group_permissions( - apiuser, repogroupid, repo_group, ('group.admin',)) + validate_repo_group_permissions(apiuser, repogroupid, repo_group, ("group.admin",)) updates = dict( - group_name=group_name - if not isinstance(group_name, Optional) else repo_group.group_name, - - group_description=description - if not isinstance(description, Optional) else repo_group.group_description, - - user=owner - if not isinstance(owner, Optional) else repo_group.user.username, - - enable_locking=enable_locking - if not isinstance(enable_locking, Optional) else repo_group.enable_locking + group_name=group_name if not isinstance(group_name, Optional) else repo_group.group_name, + group_description=description if not isinstance(description, Optional) else repo_group.group_description, + user=owner if not isinstance(owner, Optional) else repo_group.user.username, + enable_locking=enable_locking if not isinstance(enable_locking, Optional) else repo_group.enable_locking, ) schema = repo_group_schema.RepoGroupSchema().bind( # user caller user=apiuser, - old_values=repo_group.get_api_data()) + old_values=repo_group.get_api_data(), + ) try: - schema_data = schema.deserialize(dict( - repo_group_name=updates['group_name'], - repo_group_owner=updates['user'], - repo_group_description=updates['group_description'], - repo_group_enable_locking=updates['enable_locking'], - )) + schema_data = schema.deserialize( + dict( + repo_group_name=updates["group_name"], + repo_group_owner=updates["user"], + repo_group_description=updates["group_description"], + repo_group_enable_locking=updates["enable_locking"], + ) + ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) validated_updates = dict( - group_name=schema_data['repo_group']['repo_group_name_without_group'], - group_parent_id=schema_data['repo_group']['repo_group_id'], - user=schema_data['repo_group_owner'], - group_description=schema_data['repo_group_description'], - enable_locking=schema_data['repo_group_enable_locking'], + group_name=schema_data["repo_group"]["repo_group_name_without_group"], + group_parent_id=schema_data["repo_group"]["repo_group_id"], + user=schema_data["repo_group_owner"], + group_description=schema_data["repo_group_description"], + enable_locking=schema_data["repo_group_enable_locking"], ) old_data = repo_group.get_api_data() try: RepoGroupModel().update(repo_group, validated_updates) - audit_logger.store_api( - 'repo_group.edit', action_data={'old_data': old_data}, - user=apiuser) + audit_logger.store_api("repo_group.edit", action_data={"old_data": old_data}, user=apiuser) Session().commit() return { - 'msg': 'updated repository group ID:{} {}'.format( - repo_group.group_id, repo_group.group_name), - 'repo_group': repo_group.get_api_data() + "msg": "updated repository group ID:{} {}".format(repo_group.group_id, repo_group.group_name), + "repo_group": repo_group.get_api_data(), } except Exception: - log.exception( - "Exception occurred while trying update repo group %s", - repogroupid) - raise JSONRPCError('failed to update repository group `%s`' - % (repogroupid,)) + log.exception("Exception occurred while trying update repo group %s", repogroupid) + raise JSONRPCError("failed to update repository group `%s`" % (repogroupid,)) @jsonrpc_method() @@ -377,31 +384,23 @@ def delete_repo_group(request, apiuser, repogroupid): repo_group = get_repo_group_or_error(repogroupid) if not has_superadmin_permission(apiuser): - validate_repo_group_permissions( - apiuser, repogroupid, repo_group, ('group.admin',)) + validate_repo_group_permissions(apiuser, repogroupid, repo_group, ("group.admin",)) old_data = repo_group.get_api_data() try: RepoGroupModel().delete(repo_group) - audit_logger.store_api( - 'repo_group.delete', action_data={'old_data': old_data}, - user=apiuser) + audit_logger.store_api("repo_group.delete", action_data={"old_data": old_data}, user=apiuser) Session().commit() - return { - 'msg': 'deleted repo group ID:%s %s' % - (repo_group.group_id, repo_group.group_name), - 'repo_group': None - } + return {"msg": "deleted repo group ID:%s %s" % (repo_group.group_id, repo_group.group_name), "repo_group": None} except Exception: log.exception("Exception occurred while trying to delete repo group") - raise JSONRPCError('failed to delete repo group ID:%s %s' % - (repo_group.group_id, repo_group.group_name)) + raise JSONRPCError("failed to delete repo group ID:%s %s" % (repo_group.group_id, repo_group.group_name)) @jsonrpc_method() def grant_user_permission_to_repo_group( - request, apiuser, repogroupid, userid, perm, - apply_to_children=Optional('none')): + request, apiuser, repogroupid, userid, perm, apply_to_children=Optional("none") +): """ Grant permission for a user on the given repository group, or update existing permissions if found. @@ -446,50 +445,39 @@ def grant_user_permission_to_repo_group( repo_group = get_repo_group_or_error(repogroupid) if not has_superadmin_permission(apiuser): - validate_repo_group_permissions( - apiuser, repogroupid, repo_group, ('group.admin',)) + validate_repo_group_permissions(apiuser, repogroupid, repo_group, ("group.admin",)) user = get_user_or_error(userid) - perm = get_perm_or_error(perm, prefix='group.') + perm = get_perm_or_error(perm, prefix="group.") apply_to_children = Optional.extract(apply_to_children) perm_additions = [[user.user_id, perm.permission_name, "user"]] try: changes = RepoGroupModel().update_permissions( - repo_group=repo_group, perm_additions=perm_additions, - recursive=apply_to_children, cur_user=apiuser) + repo_group=repo_group, perm_additions=perm_additions, recursive=apply_to_children, cur_user=apiuser + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("repo_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Granted perm: `%s` (recursive:%s) for user: ' - '`%s` in repo group: `%s`' % ( - perm.permission_name, apply_to_children, user.username, - repo_group.name - ), - 'success': True + "msg": "Granted perm: `%s` (recursive:%s) for user: " + "`%s` in repo group: `%s`" % (perm.permission_name, apply_to_children, user.username, repo_group.name), + "success": True, } except Exception: - log.exception("Exception occurred while trying to grant " - "user permissions to repo group") - raise JSONRPCError( - 'failed to edit permission for user: ' - '`%s` in repo group: `%s`' % (userid, repo_group.name)) + log.exception("Exception occurred while trying to grant user permissions to repo group") + raise JSONRPCError("failed to edit permission for user: `%s` in repo group: `%s`" % (userid, repo_group.name)) @jsonrpc_method() -def revoke_user_permission_from_repo_group( - request, apiuser, repogroupid, userid, - apply_to_children=Optional('none')): +def revoke_user_permission_from_repo_group(request, apiuser, repogroupid, userid, apply_to_children=Optional("none")): """ Revoke permission for a user in a given repository group. @@ -531,8 +519,7 @@ def revoke_user_permission_from_repo_group( repo_group = get_repo_group_or_error(repogroupid) if not has_superadmin_permission(apiuser): - validate_repo_group_permissions( - apiuser, repogroupid, repo_group, ('group.admin',)) + validate_repo_group_permissions(apiuser, repogroupid, repo_group, ("group.admin",)) user = get_user_or_error(userid) apply_to_children = Optional.extract(apply_to_children) @@ -540,39 +527,37 @@ def revoke_user_permission_from_repo_group( perm_deletions = [[user.user_id, None, "user"]] try: changes = RepoGroupModel().update_permissions( - repo_group=repo_group, perm_deletions=perm_deletions, - recursive=apply_to_children, cur_user=apiuser) + repo_group=repo_group, perm_deletions=perm_deletions, recursive=apply_to_children, cur_user=apiuser + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("repo_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Revoked perm (recursive:%s) for user: ' - '`%s` in repo group: `%s`' % ( - apply_to_children, user.username, repo_group.name - ), - 'success': True + "msg": "Revoked perm (recursive:%s) for user: " + "`%s` in repo group: `%s`" % (apply_to_children, user.username, repo_group.name), + "success": True, } except Exception: - log.exception("Exception occurred while trying revoke user " - "permission from repo group") - raise JSONRPCError( - 'failed to edit permission for user: ' - '`%s` in repo group: `%s`' % (userid, repo_group.name)) + log.exception("Exception occurred while trying revoke user permission from repo group") + raise JSONRPCError("failed to edit permission for user: `%s` in repo group: `%s`" % (userid, repo_group.name)) @jsonrpc_method() def grant_user_group_permission_to_repo_group( - request, apiuser, repogroupid, usergroupid, perm, - apply_to_children=Optional('none'), ): + request, + apiuser, + repogroupid, + usergroupid, + perm, + apply_to_children=Optional("none"), +): """ Grant permission for a user group on given repository group, or update existing permissions if found. @@ -616,61 +601,54 @@ def grant_user_group_permission_to_repo_group( """ repo_group = get_repo_group_or_error(repogroupid) - perm = get_perm_or_error(perm, prefix='group.') + perm = get_perm_or_error(perm, prefix="group.") user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): - validate_repo_group_permissions( - apiuser, repogroupid, repo_group, ('group.admin',)) + validate_repo_group_permissions(apiuser, repogroupid, repo_group, ("group.admin",)) # check if we have at least read permission for this user group ! - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") apply_to_children = Optional.extract(apply_to_children) perm_additions = [[user_group.users_group_id, perm.permission_name, "user_group"]] try: changes = RepoGroupModel().update_permissions( - repo_group=repo_group, perm_additions=perm_additions, - recursive=apply_to_children, cur_user=apiuser) + repo_group=repo_group, perm_additions=perm_additions, recursive=apply_to_children, cur_user=apiuser + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("repo_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Granted perm: `%s` (recursive:%s) ' - 'for user group: `%s` in repo group: `%s`' % ( - perm.permission_name, apply_to_children, - user_group.users_group_name, repo_group.name - ), - 'success': True + "msg": "Granted perm: `%s` (recursive:%s) " + "for user group: `%s` in repo group: `%s`" + % (perm.permission_name, apply_to_children, user_group.users_group_name, repo_group.name), + "success": True, } except Exception: - log.exception("Exception occurred while trying to grant user " - "group permissions to repo group") + log.exception("Exception occurred while trying to grant user group permissions to repo group") raise JSONRPCError( - 'failed to edit permission for user group: `%s` in ' - 'repo group: `%s`' % ( - usergroupid, repo_group.name - ) + "failed to edit permission for user group: `%s` in repo group: `%s`" % (usergroupid, repo_group.name) ) @jsonrpc_method() def revoke_user_group_permission_from_repo_group( - request, apiuser, repogroupid, usergroupid, - apply_to_children=Optional('none')): + request, apiuser, repogroupid, usergroupid, apply_to_children=Optional("none") +): """ Revoke permission for user group on given repository. @@ -712,49 +690,42 @@ def revoke_user_group_permission_from_repo_group( repo_group = get_repo_group_or_error(repogroupid) user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): - validate_repo_group_permissions( - apiuser, repogroupid, repo_group, ('group.admin',)) + validate_repo_group_permissions(apiuser, repogroupid, repo_group, ("group.admin",)) # check if we have at least read permission for this user group ! - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") apply_to_children = Optional.extract(apply_to_children) perm_deletions = [[user_group.users_group_id, None, "user_group"]] try: changes = RepoGroupModel().update_permissions( - repo_group=repo_group, perm_deletions=perm_deletions, - recursive=apply_to_children, cur_user=apiuser) + repo_group=repo_group, perm_deletions=perm_deletions, recursive=apply_to_children, cur_user=apiuser + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'repo_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("repo_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Revoked perm (recursive:%s) for user group: ' - '`%s` in repo group: `%s`' % ( - apply_to_children, user_group.users_group_name, - repo_group.name - ), - 'success': True + "msg": "Revoked perm (recursive:%s) for user group: " + "`%s` in repo group: `%s`" % (apply_to_children, user_group.users_group_name, repo_group.name), + "success": True, } except Exception: - log.exception("Exception occurred while trying revoke user group " - "permissions from repo group") + log.exception("Exception occurred while trying revoke user group permissions from repo group") raise JSONRPCError( - 'failed to edit permission for user group: ' - '`%s` in repo group: `%s`' % ( - user_group.users_group_name, repo_group.name - ) + "failed to edit permission for user group: " + "`%s` in repo group: `%s`" % (user_group.users_group_name, repo_group.name) ) diff --git a/rhodecode/api/views/search_api.py b/rhodecode/api/views/search_api.py index 183f4c46..dce2f7dd 100644 --- a/rhodecode/api/views/search_api.py +++ b/rhodecode/api/views/search_api.py @@ -32,9 +32,17 @@ log = logging.getLogger(__name__) @jsonrpc_method() -def search(request, apiuser, search_query, search_type, page_limit=Optional(10), - page=Optional(1), search_sort=Optional('desc:date'), - repo_name=Optional(None), repo_group_name=Optional(None)): +def search( + request, + apiuser, + search_query, + search_type, + page_limit=Optional(10), + page=Optional(1), + search_sort=Optional("desc:date"), + repo_name=Optional(None), + repo_group_name=Optional(None), +): """ Fetch Full Text Search results using API. @@ -67,7 +75,7 @@ def search(request, apiuser, search_query, search_type, page_limit=Optional(10), :type repo_group_name: Optional(str) """ - data = {'execution_time': ''} + data = {"execution_time": ""} repo_name = Optional.extract(repo_name) repo_group_name = Optional.extract(repo_group_name) @@ -75,45 +83,57 @@ def search(request, apiuser, search_query, search_type, page_limit=Optional(10), try: search_params = schema.deserialize( - dict(search_query=search_query, - search_type=search_type, - search_sort=Optional.extract(search_sort), - page_limit=Optional.extract(page_limit), - requested_page=Optional.extract(page)) + dict( + search_query=search_query, + search_type=search_type, + search_sort=Optional.extract(search_sort), + page_limit=Optional.extract(page_limit), + requested_page=Optional.extract(page), + ) ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) - search_query = search_params.get('search_query') - search_type = search_params.get('search_type') - search_sort = search_params.get('search_sort') + search_query = search_params.get("search_query") + search_type = search_params.get("search_type") + search_sort = search_params.get("search_sort") - if search_params.get('search_query'): - page_limit = search_params['page_limit'] - requested_page = search_params['requested_page'] + if search_params.get("search_query"): + page_limit = search_params["page_limit"] + requested_page = search_params["requested_page"] searcher = searcher_from_config(request.registry.settings) try: search_result = searcher.search( - search_query, search_type, apiuser, repo_name, repo_group_name, - requested_page=requested_page, page_limit=page_limit, sort=search_sort) + search_query, + search_type, + apiuser, + repo_name, + repo_group_name, + requested_page=requested_page, + page_limit=page_limit, + sort=search_sort, + ) - data.update(dict( - results=list(search_result['results']), page=requested_page, - item_count=search_result['count'], - items_per_page=page_limit)) + data.update( + dict( + results=list(search_result["results"]), + page=requested_page, + item_count=search_result["count"], + items_per_page=page_limit, + ) + ) finally: searcher.cleanup() - if not search_result['error']: - data['execution_time'] = '{} results ({:.4f} seconds)'.format( - search_result['count'], - search_result['runtime']) + if not search_result["error"]: + data["execution_time"] = "{} results ({:.4f} seconds)".format( + search_result["count"], search_result["runtime"] + ) else: - node = schema['search_query'] - raise JSONRPCValidationError( - colander_exc=validation_schema.Invalid(node, search_result['error'])) + node = schema["search_query"] + raise JSONRPCValidationError(colander_exc=validation_schema.Invalid(node, search_result["error"])) return data @@ -138,10 +158,12 @@ def get_audit_logs(request, apiuser, query): ret = [] # show all user actions - user_log = UserLog.query() \ - .options(joinedload(UserLog.user)) \ - .options(joinedload(UserLog.repository)) \ + user_log = ( + UserLog.query() + .options(joinedload(UserLog.user)) + .options(joinedload(UserLog.repository)) .order_by(UserLog.action_date.desc()) + ) audit_log = user_log_filter(user_log, filter_term) diff --git a/rhodecode/api/views/server_api.py b/rhodecode/api/views/server_api.py index 150e4660..9373b4e5 100644 --- a/rhodecode/api/views/server_api.py +++ b/rhodecode/api/views/server_api.py @@ -19,11 +19,9 @@ import logging import itertools -from rhodecode.api import ( - jsonrpc_method, JSONRPCError, JSONRPCForbidden, find_methods) +from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden, find_methods -from rhodecode.api.utils import ( - Optional, OAttr, has_superadmin_permission, get_user_or_error) +from rhodecode.api.utils import Optional, OAttr, has_superadmin_permission, get_user_or_error from rhodecode.lib.utils import get_rhodecode_repo_store_path from rhodecode.lib import system_info from rhodecode.lib import user_sessions @@ -68,8 +66,8 @@ def get_server_info(request, apiuser): server_info = ScmModel().get_server_info(request.environ) # rhodecode-index requires those - server_info['index_storage'] = server_info['search']['value']['location'] - server_info['storage'] = server_info['storage']['value']['path'] + server_info["index_storage"] = server_info["search"]["value"]["location"] + server_info["storage"] = server_info["storage"]["value"]["path"] return server_info @@ -104,7 +102,7 @@ def get_repo_store(request, apiuser): @jsonrpc_method() -def get_ip(request, apiuser, userid=Optional(OAttr('apiuser'))): +def get_ip(request, apiuser, userid=Optional(OAttr("apiuser"))): """ Displays the IP Address as seen from the |RCE| server. @@ -144,14 +142,11 @@ def get_ip(request, apiuser, userid=Optional(OAttr('apiuser'))): raise JSONRPCForbidden() userid = Optional.extract(userid, evaluate_locals=locals()) - userid = getattr(userid, 'user_id', userid) + userid = getattr(userid, "user_id", userid) user = get_user_or_error(userid) ips = UserIpMap.query().filter(UserIpMap.user == user).all() - return { - 'server_ip_addr': request.rpc_ip_addr, - 'user_ips': ips - } + return {"server_ip_addr": request.rpc_ip_addr, "user_ips": ips} @jsonrpc_method() @@ -190,19 +185,18 @@ def rescan_repos(request, apiuser): } """ - from rhodecode.lib.utils import repo2db_mapper # re-import for testing patches + from rhodecode.lib.utils import repo2db_mapper # re-import for testing patches if not has_superadmin_permission(apiuser): raise JSONRPCForbidden() try: added, errors = repo2db_mapper(ScmModel().repo_scan(), force_hooks_rebuild=True) - return {'added': added, 'errors': errors} + return {"added": added, "errors": errors} except Exception: - log.exception('Failed to run repo rescan') - raise JSONRPCError( - 'Error occurred during rescan repositories action' - ) + log.exception("Failed to run repo rescan") + raise JSONRPCError("Error occurred during rescan repositories action") + @jsonrpc_method() def cleanup_repos(request, apiuser): @@ -246,12 +240,10 @@ def cleanup_repos(request, apiuser): try: removed, errors = repo2db_cleanup() - return {'removed': removed, 'errors': errors} + return {"removed": removed, "errors": errors} except Exception: - log.exception('Failed to run repo storage cleanup') - raise JSONRPCError( - 'Error occurred during repo storage cleanup action' - ) + log.exception("Failed to run repo storage cleanup") + raise JSONRPCError("Error occurred during repo storage cleanup action") @jsonrpc_method() @@ -301,26 +293,22 @@ def cleanup_sessions(request, apiuser, older_then=Optional(60)): older_then = safe_int(Optional.extract(older_then)) or 60 older_than_seconds = 60 * 60 * 24 * older_then - config = system_info.rhodecode_config().get_value()['value']['config'] - session_model = user_sessions.get_session_handler( - config.get('beaker.session.type', 'memory'))(config) + config = system_info.rhodecode_config().get_value()["value"]["config"] + session_model = user_sessions.get_session_handler(config.get("beaker.session.type", "memory"))(config) backend = session_model.SESSION_TYPE try: - cleaned = session_model.clean_sessions( - older_than_seconds=older_than_seconds) - return {'sessions_removed': cleaned, 'backend': backend} + cleaned = session_model.clean_sessions(older_than_seconds=older_than_seconds) + return {"sessions_removed": cleaned, "backend": backend} except user_sessions.CleanupCommand as msg: - return {'cleanup_command': str(msg), 'backend': backend} + return {"cleanup_command": str(msg), "backend": backend} except Exception as e: - log.exception('Failed session cleanup') - raise JSONRPCError( - 'Error occurred during session cleanup' - ) + log.exception("Failed session cleanup") + raise JSONRPCError("Error occurred during session cleanup") @jsonrpc_method() -def get_method(request, apiuser, pattern=Optional('*')): +def get_method(request, apiuser, pattern=Optional("*")): """ Returns list of all available API methods. By default match pattern os "*" but any other pattern can be specified. eg *comment* will return @@ -369,6 +357,7 @@ def get_method(request, apiuser, pattern=Optional('*')): error : null """ from rhodecode.config import patches + inspect = patches.inspect_getargspec() if not has_superadmin_permission(apiuser): @@ -387,18 +376,17 @@ def get_method(request, apiuser, pattern=Optional('*')): arglist = argspec[0] defaults = list(map(repr, argspec[3] or [])) - default_empty = '' + default_empty = "" # kw arguments required by this method - func_kwargs = dict(itertools.zip_longest( - reversed(arglist), reversed(defaults), fillvalue=default_empty)) + func_kwargs = dict(itertools.zip_longest(reversed(arglist), reversed(defaults), fillvalue=default_empty)) args_desc.append(func_kwargs) return matches_keys + args_desc @jsonrpc_method() -def store_exception(request, apiuser, exc_data_json, prefix=Optional('rhodecode')): +def store_exception(request, apiuser, exc_data_json, prefix=Optional("rhodecode")): """ Stores sent exception inside the built-in exception tracker in |RCE| server. @@ -437,27 +425,24 @@ def store_exception(request, apiuser, exc_data_json, prefix=Optional('rhodecode' try: exc_data = json.loads(exc_data_json) except Exception: - log.error('Failed to parse JSON: %r', exc_data_json) - raise JSONRPCError('Failed to parse JSON data from exc_data_json field. ' - 'Please make sure it contains a valid JSON.') + log.error("Failed to parse JSON: %r", exc_data_json) + raise JSONRPCError( + "Failed to parse JSON data from exc_data_json field. Please make sure it contains a valid JSON." + ) try: - exc_traceback = exc_data['exc_traceback'] - exc_type_name = exc_data['exc_type_name'] - exc_value = '' + exc_traceback = exc_data["exc_traceback"] + exc_type_name = exc_data["exc_type_name"] + exc_value = "" except KeyError as err: - raise JSONRPCError( - f'Missing exc_traceback, or exc_type_name ' - f'in exc_data_json field. Missing: {err}') + raise JSONRPCError(f"Missing exc_traceback, or exc_type_name in exc_data_json field. Missing: {err}") class ExcType: __name__ = exc_type_name exc_info = (ExcType(), exc_value, exc_traceback) - exc_tracking._store_exception( - exc_id=exc_id, exc_info=exc_info, prefix=prefix) + exc_tracking._store_exception(exc_id=exc_id, exc_info=exc_info, prefix=prefix) - exc_url = request.route_url( - 'admin_settings_exception_tracker_show', exception_id=exc_id) - return {'exc_id': exc_id, 'exc_url': exc_url} + exc_url = request.route_url("admin_settings_exception_tracker_show", exception_id=exc_id) + return {"exc_id": exc_id, "exc_url": exc_url} diff --git a/rhodecode/api/views/testing_api.py b/rhodecode/api/views/testing_api.py index 4501f43c..7d03e30d 100644 --- a/rhodecode/api/views/testing_api.py +++ b/rhodecode/api/views/testing_api.py @@ -37,53 +37,37 @@ def test(request, apiuser, args): @jsonrpc_method() def test_ok(request, apiuser): return { - 'who': f'hello {apiuser}', - 'obj': { - 'time': time.time(), - 'dt': datetime.datetime.now(), - 'decimal': decimal.Decimal('0.123') - } + "who": f"hello {apiuser}", + "obj": {"time": time.time(), "dt": datetime.datetime.now(), "decimal": decimal.Decimal("0.123")}, } @jsonrpc_method() def test_error(request, apiuser): - raise JSONRPCError('error happened') + raise JSONRPCError("error happened") @jsonrpc_method() def test_exception(request, apiuser): - raise Exception('something unhandled') + raise Exception("something unhandled") @jsonrpc_method() def test_params(request, apiuser, params): - return { - 'who': f'hello {apiuser}', - 'params': params - } + return {"who": f"hello {apiuser}", "params": params} @jsonrpc_method() -def test_params_opt( - request, apiuser, params, opt1=False, opt2=Optional(True), - opt3=Optional(OAttr('apiuser'))): +def test_params_opt(request, apiuser, params, opt1=False, opt2=Optional(True), opt3=Optional(OAttr("apiuser"))): opt2 = Optional.extract(opt2) opt3 = Optional.extract(opt3, evaluate_locals=locals()) - return { - 'who': f'hello {apiuser}', - 'params': params, - 'opts': [ - opt1, opt2, opt3 - ] - } + return {"who": f"hello {apiuser}", "params": params, "opts": [opt1, opt2, opt3]} @jsonrpc_method() -@jsonrpc_deprecated_method( - use_method='test_ok', deprecated_at_version='4.0.0') +@jsonrpc_deprecated_method(use_method="test_ok", deprecated_at_version="4.0.0") def test_deprecated_method(request, apiuser): - return 'value' + return "value" @jsonrpc_method() diff --git a/rhodecode/api/views/user_api.py b/rhodecode/api/views/user_api.py index 5954e510..2dc48dde 100644 --- a/rhodecode/api/views/user_api.py +++ b/rhodecode/api/views/user_api.py @@ -18,10 +18,8 @@ import logging -from rhodecode.api import ( - jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError) -from rhodecode.api.utils import ( - Optional, OAttr, has_superadmin_permission, get_user_or_error, store_update) +from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError +from rhodecode.api.utils import Optional, OAttr, has_superadmin_permission, get_user_or_error, store_update from rhodecode.lib import audit_logger from rhodecode.lib.auth import AuthUser, PasswordGenerator from rhodecode.lib.exceptions import DefaultUserException @@ -35,7 +33,7 @@ log = logging.getLogger(__name__) @jsonrpc_method() -def get_user(request, apiuser, userid=Optional(OAttr('apiuser'))): +def get_user(request, apiuser, userid=Optional(OAttr("apiuser"))): """ Returns the information associated with a username or userid. @@ -108,16 +106,16 @@ def get_user(request, apiuser, userid=Optional(OAttr('apiuser'))): # make sure normal user does not pass someone else userid, # he is not allowed to do that if not isinstance(userid, Optional) and userid != apiuser.user_id: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") userid = Optional.extract(userid, evaluate_locals=locals()) - userid = getattr(userid, 'user_id', userid) + userid = getattr(userid, "user_id", userid) user = get_user_or_error(userid) data = user.get_api_data(include_secrets=True) permissions = AuthUser(user_id=user.user_id).permissions - data['permissions'] = permissions # TODO(marcink): should be deprecated - data['permissions_summary'] = permissions + data["permissions"] = permissions # TODO(marcink): should be deprecated + data["permissions_summary"] = permissions return data @@ -147,22 +145,29 @@ def get_users(request, apiuser): raise JSONRPCForbidden() result = [] - users_list = User.query().order_by(User.username) \ - .filter(User.username != User.DEFAULT_USER) \ - .all() + users_list = User.query().order_by(User.username).filter(User.username != User.DEFAULT_USER).all() for user in users_list: result.append(user.get_api_data(include_secrets=True)) return result @jsonrpc_method() -def create_user(request, apiuser, username, email, password=Optional(''), - firstname=Optional(''), lastname=Optional(''), description=Optional(''), - active=Optional(True), admin=Optional(False), - extern_name=Optional('rhodecode'), - extern_type=Optional('rhodecode'), - force_password_change=Optional(False), - create_personal_repo_group=Optional(None)): +def create_user( + request, + apiuser, + username, + email, + password=Optional(""), + firstname=Optional(""), + lastname=Optional(""), + description=Optional(""), + active=Optional(True), + admin=Optional(False), + extern_name=Optional("rhodecode"), + extern_type=Optional("rhodecode"), + force_password_change=Optional(False), + create_personal_repo_group=Optional(None), +): """ Creates a new user and returns the new user object. @@ -237,8 +242,7 @@ def create_user(request, apiuser, username, email, password=Optional(''), # generate random password if we actually given the # extern_name and it's not rhodecode - if (not isinstance(extern_name, Optional) and - Optional.extract(extern_name) != 'rhodecode'): + if not isinstance(extern_name, Optional) and Optional.extract(extern_name) != "rhodecode": # generate temporary password if user is external password = PasswordGenerator().gen_password(length=16) create_repo_group = Optional.extract(create_personal_repo_group) @@ -258,60 +262,68 @@ def create_user(request, apiuser, username, email, password=Optional(''), schema = user_schema.UserSchema().bind( # user caller - user=apiuser) + user=apiuser + ) try: - schema_data = schema.deserialize(dict( - username=username, - email=email, - password=password, - first_name=first_name, - last_name=last_name, - active=active, - admin=admin, - description=description, - extern_type=extern_type, - extern_name=extern_name, - )) + schema_data = schema.deserialize( + dict( + username=username, + email=email, + password=password, + first_name=first_name, + last_name=last_name, + active=active, + admin=admin, + description=description, + extern_type=extern_type, + extern_name=extern_name, + ) + ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) try: user = UserModel().create_or_update( - username=schema_data['username'], - password=schema_data['password'], - email=schema_data['email'], - firstname=schema_data['first_name'], - lastname=schema_data['last_name'], - description=schema_data['description'], - active=schema_data['active'], - admin=schema_data['admin'], - extern_type=schema_data['extern_type'], - extern_name=schema_data['extern_name'], + username=schema_data["username"], + password=schema_data["password"], + email=schema_data["email"], + firstname=schema_data["first_name"], + lastname=schema_data["last_name"], + description=schema_data["description"], + active=schema_data["active"], + admin=schema_data["admin"], + extern_type=schema_data["extern_type"], + extern_name=schema_data["extern_name"], force_password_change=Optional.extract(force_password_change), - create_repo_group=create_repo_group + create_repo_group=create_repo_group, ) Session().flush() creation_data = user.get_api_data() - audit_logger.store_api( - 'user.create', action_data={'data': creation_data}, - user=apiuser) + audit_logger.store_api("user.create", action_data={"data": creation_data}, user=apiuser) Session().commit() - return { - 'msg': 'created new user `%s`' % username, - 'user': user.get_api_data(include_secrets=True) - } + return {"msg": "created new user `%s`" % username, "user": user.get_api_data(include_secrets=True)} except Exception: - log.exception('Error occurred during creation of user') - raise JSONRPCError(f'failed to create user `{username}`') + log.exception("Error occurred during creation of user") + raise JSONRPCError(f"failed to create user `{username}`") @jsonrpc_method() -def update_user(request, apiuser, userid, username=Optional(None), - email=Optional(None), password=Optional(None), - firstname=Optional(None), lastname=Optional(None), - description=Optional(None), active=Optional(None), admin=Optional(None), - extern_type=Optional(None), extern_name=Optional(None), ): +def update_user( + request, + apiuser, + userid, + username=Optional(None), + email=Optional(None), + password=Optional(None), + firstname=Optional(None), + lastname=Optional(None), + description=Optional(None), + active=Optional(None), + admin=Optional(None), + extern_type=Optional(None), + extern_name=Optional(None), +): """ Updates the details for the specified user, if that user exists. @@ -378,33 +390,30 @@ def update_user(request, apiuser, userid, username=Optional(None), updates = {} try: - - store_update(updates, username, 'username') - store_update(updates, password, 'password') - store_update(updates, email, 'email') - store_update(updates, firstname, 'name') - store_update(updates, lastname, 'lastname') - store_update(updates, description, 'description') - store_update(updates, active, 'active') - store_update(updates, admin, 'admin') - store_update(updates, extern_name, 'extern_name') - store_update(updates, extern_type, 'extern_type') + store_update(updates, username, "username") + store_update(updates, password, "password") + store_update(updates, email, "email") + store_update(updates, firstname, "name") + store_update(updates, lastname, "lastname") + store_update(updates, description, "description") + store_update(updates, active, "active") + store_update(updates, admin, "admin") + store_update(updates, extern_name, "extern_name") + store_update(updates, extern_type, "extern_type") user = UserModel().update_user(user, **updates) - audit_logger.store_api( - 'user.edit', action_data={'old_data': old_data}, - user=apiuser) + audit_logger.store_api("user.edit", action_data={"old_data": old_data}, user=apiuser) Session().commit() return { - 'msg': f'updated user ID:{user.user_id} {user.username}', - 'user': user.get_api_data(include_secrets=True) + "msg": f"updated user ID:{user.user_id} {user.username}", + "user": user.get_api_data(include_secrets=True), } except DefaultUserException: log.exception("Default user edit exception") - raise JSONRPCError('editing default user is forbidden') + raise JSONRPCError("editing default user is forbidden") except Exception: log.exception("Error occurred during update of user") - raise JSONRPCError(f'failed to update user `{userid}`') + raise JSONRPCError(f"failed to update user `{userid}`") @jsonrpc_method() @@ -459,23 +468,17 @@ def delete_user(request, apiuser, userid): old_data = user.get_api_data() try: UserModel().delete(userid) - audit_logger.store_api( - 'user.delete', action_data={'old_data': old_data}, - user=apiuser) + audit_logger.store_api("user.delete", action_data={"old_data": old_data}, user=apiuser) Session().commit() - return { - 'msg': f'deleted user ID:{user.user_id} {user.username}', - 'user': None - } + return {"msg": f"deleted user ID:{user.user_id} {user.username}", "user": None} except Exception: log.exception("Error occurred during deleting of user") - raise JSONRPCError( - f'failed to delete user ID:{user.user_id} {user.username}') + raise JSONRPCError(f"failed to delete user ID:{user.user_id} {user.username}") @jsonrpc_method() -def get_user_locks(request, apiuser, userid=Optional(OAttr('apiuser'))): +def get_user_locks(request, apiuser, userid=Optional(OAttr("apiuser"))): """ Displays all repositories locked by the specified user. @@ -506,12 +509,12 @@ def get_user_locks(request, apiuser, userid=Optional(OAttr('apiuser'))): # make sure normal user does not pass someone else userid, # he is not allowed to do that if not isinstance(userid, Optional) and userid != apiuser.user_id: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") else: include_secrets = True userid = Optional.extract(userid, evaluate_locals=locals()) - userid = getattr(userid, 'user_id', userid) + userid = getattr(userid, "user_id", userid) user = get_user_or_error(userid) ret = [] @@ -529,7 +532,7 @@ def get_user_locks(request, apiuser, userid=Optional(OAttr('apiuser'))): @jsonrpc_method() -def get_user_audit_logs(request, apiuser, userid=Optional(OAttr('apiuser'))): +def get_user_audit_logs(request, apiuser, userid=Optional(OAttr("apiuser"))): """ Fetches all action logs made by the specified user. @@ -556,10 +559,10 @@ def get_user_audit_logs(request, apiuser, userid=Optional(OAttr('apiuser'))): # make sure normal user does not pass someone else userid, # he is not allowed to do that if not isinstance(userid, Optional) and userid != apiuser.user_id: - raise JSONRPCError('userid is not the same as your user') + raise JSONRPCError("userid is not the same as your user") userid = Optional.extract(userid, evaluate_locals=locals()) - userid = getattr(userid, 'user_id', userid) + userid = getattr(userid, "user_id", userid) user = get_user_or_error(userid) ret = [] diff --git a/rhodecode/api/views/user_group_api.py b/rhodecode/api/views/user_group_api.py index 2862583f..6a34ada5 100644 --- a/rhodecode/api/views/user_group_api.py +++ b/rhodecode/api/views/user_group_api.py @@ -18,11 +18,17 @@ import logging -from rhodecode.api import ( - jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError) +from rhodecode.api import jsonrpc_method, JSONRPCError, JSONRPCForbidden, JSONRPCValidationError from rhodecode.api.utils import ( - Optional, OAttr, store_update, has_superadmin_permission, get_origin, - get_user_or_error, get_user_group_or_error, get_perm_or_error) + Optional, + OAttr, + store_update, + has_superadmin_permission, + get_origin, + get_user_or_error, + get_user_group_or_error, + get_perm_or_error, +) from rhodecode.lib import audit_logger from rhodecode.lib.auth import HasUserGroupPermissionAnyApi, HasPermissionAnyApi from rhodecode.lib.exceptions import UserGroupAssignedException @@ -98,35 +104,36 @@ def get_user_group(request, apiuser, usergroupid): user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): # check if we have at least read permission for this user group ! - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError('user group `{}` does not exist'.format( - usergroupid)) + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError("user group `{}` does not exist".format(usergroupid)) permissions = [] for _user in user_group.permissions(): user_data = { - 'name': _user.username, - 'permission': _user.permission, - 'origin': get_origin(_user), - 'type': "user", + "name": _user.username, + "permission": _user.permission, + "origin": get_origin(_user), + "type": "user", } permissions.append(user_data) for _user_group in user_group.permission_user_groups(): user_group_data = { - 'name': _user_group.users_group_name, - 'permission': _user_group.permission, - 'origin': get_origin(_user_group), - 'type': "user_group", + "name": _user_group.users_group_name, + "permission": _user_group.permission, + "origin": get_origin(_user_group), + "type": "user_group", } permissions.append(user_group_data) data = user_group.get_api_data() data["permissions"] = permissions - data["permissions_summary"] = UserGroupModel().get_perms_summary( - user_group.users_group_id) + data["permissions_summary"] = UserGroupModel().get_perms_summary(user_group.users_group_id) return data @@ -155,20 +162,27 @@ def get_user_groups(request, apiuser): include_secrets = has_superadmin_permission(apiuser) result = [] - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - extras = {'user': apiuser} - for user_group in UserGroupList(UserGroupModel().get_all(), - perm_set=_perms, extra_kwargs=extras): - result.append( - user_group.get_api_data(include_secrets=include_secrets)) + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + extras = {"user": apiuser} + for user_group in UserGroupList(UserGroupModel().get_all(), perm_set=_perms, extra_kwargs=extras): + result.append(user_group.get_api_data(include_secrets=include_secrets)) return result @jsonrpc_method() def create_user_group( - request, apiuser, group_name, description=Optional(''), - owner=Optional(OAttr('apiuser')), active=Optional(True), - sync=Optional(None)): + request, + apiuser, + group_name, + description=Optional(""), + owner=Optional(OAttr("apiuser")), + active=Optional(True), + sync=Optional(None), +): """ Creates a new user group. @@ -220,7 +234,7 @@ def create_user_group( """ if not has_superadmin_permission(apiuser): - if not HasPermissionAnyApi('hg.usergroup.create.true')(user=apiuser): + if not HasPermissionAnyApi("hg.usergroup.create.true")(user=apiuser): raise JSONRPCForbidden() if UserGroupModel().get_by_name(group_name): @@ -237,53 +251,57 @@ def create_user_group( # set the sync option based on group_data group_data = None if sync: - group_data = { - 'extern_type': 'manual_api', - 'extern_type_set_by': apiuser.username - } + group_data = {"extern_type": "manual_api", "extern_type_set_by": apiuser.username} schema = user_group_schema.UserGroupSchema().bind( # user caller - user=apiuser) + user=apiuser + ) try: - schema_data = schema.deserialize(dict( - user_group_name=group_name, - user_group_description=description, - user_group_owner=owner.username, - user_group_active=active, - )) + schema_data = schema.deserialize( + dict( + user_group_name=group_name, + user_group_description=description, + user_group_owner=owner.username, + user_group_active=active, + ) + ) except validation_schema.Invalid as err: raise JSONRPCValidationError(colander_exc=err) try: user_group = UserGroupModel().create( - name=schema_data['user_group_name'], - description=schema_data['user_group_description'], + name=schema_data["user_group_name"], + description=schema_data["user_group_description"], owner=owner, - active=schema_data['user_group_active'], group_data=group_data) + active=schema_data["user_group_active"], + group_data=group_data, + ) Session().flush() creation_data = user_group.get_api_data() - audit_logger.store_api( - 'user_group.create', action_data={'data': creation_data}, - user=apiuser) + audit_logger.store_api("user_group.create", action_data={"data": creation_data}, user=apiuser) Session().commit() affected_user_ids = [apiuser.user_id, owner.user_id] PermissionModel().trigger_permission_flush(affected_user_ids) - return { - 'msg': 'created new user group `%s`' % group_name, - 'user_group': creation_data - } + return {"msg": "created new user group `%s`" % group_name, "user_group": creation_data} except Exception: log.exception("Error occurred during creation of user group") - raise JSONRPCError(f'failed to create group `{group_name}`') + raise JSONRPCError(f"failed to create group `{group_name}`") @jsonrpc_method() -def update_user_group(request, apiuser, usergroupid, group_name=Optional(''), - description=Optional(''), owner=Optional(None), - active=Optional(True), sync=Optional(None)): +def update_user_group( + request, + apiuser, + usergroupid, + group_name=Optional(""), + description=Optional(""), + owner=Optional(None), + active=Optional(True), + sync=Optional(None), +): """ Updates the specified `user group` with the details provided. @@ -335,11 +353,9 @@ def update_user_group(request, apiuser, usergroupid, group_name=Optional(''), include_secrets = False if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") else: include_secrets = True @@ -348,18 +364,15 @@ def update_user_group(request, apiuser, usergroupid, group_name=Optional(''), old_data = user_group.get_api_data() updates = {} - store_update(updates, group_name, 'users_group_name') - store_update(updates, description, 'user_group_description') - store_update(updates, owner, 'user') - store_update(updates, active, 'users_group_active') + store_update(updates, group_name, "users_group_name") + store_update(updates, description, "user_group_description") + store_update(updates, owner, "user") + store_update(updates, active, "users_group_active") sync = Optional.extract(sync) group_data = None if sync is True: - group_data = { - 'extern_type': 'manual_api', - 'extern_type_set_by': apiuser.username - } + group_data = {"extern_type": "manual_api", "extern_type_set_by": apiuser.username} if sync is False: group_data = user_group.group_data if group_data and "extern_type" in group_data: @@ -367,20 +380,15 @@ def update_user_group(request, apiuser, usergroupid, group_name=Optional(''), try: UserGroupModel().update(user_group, updates, group_data=group_data) - audit_logger.store_api( - 'user_group.edit', action_data={'old_data': old_data}, - user=apiuser) + audit_logger.store_api("user_group.edit", action_data={"old_data": old_data}, user=apiuser) Session().commit() return { - 'msg': 'updated user group ID:{} {}'.format( - user_group.users_group_id, user_group.users_group_name), - 'user_group': user_group.get_api_data( - include_secrets=include_secrets) + "msg": "updated user group ID:{} {}".format(user_group.users_group_id, user_group.users_group_name), + "user_group": user_group.get_api_data(include_secrets=include_secrets), } except Exception: log.exception("Error occurred during update of user group") - raise JSONRPCError( - f'failed to update user group `{usergroupid}`') + raise JSONRPCError(f"failed to update user group `{usergroupid}`") @jsonrpc_method() @@ -425,23 +433,18 @@ def delete_user_group(request, apiuser, usergroupid): user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") old_data = user_group.get_api_data() try: UserGroupModel().delete(user_group) - audit_logger.store_api( - 'user_group.delete', action_data={'old_data': old_data}, - user=apiuser) + audit_logger.store_api("user_group.delete", action_data={"old_data": old_data}, user=apiuser) Session().commit() return { - 'msg': 'deleted user group ID:{} {}'.format( - user_group.users_group_id, user_group.users_group_name), - 'user_group': None + "msg": "deleted user group ID:{} {}".format(user_group.users_group_id, user_group.users_group_name), + "user_group": None, } except UserGroupAssignedException as e: log.exception("UserGroupAssigned error") @@ -449,8 +452,8 @@ def delete_user_group(request, apiuser, usergroupid): except Exception: log.exception("Error occurred during deletion of user group") raise JSONRPCError( - 'failed to delete user group ID:%s %s' %( - user_group.users_group_id, user_group.users_group_name)) + "failed to delete user group ID:%s %s" % (user_group.users_group_id, user_group.users_group_name) + ) @jsonrpc_method() @@ -501,37 +504,29 @@ def add_user_to_user_group(request, apiuser, usergroupid, userid): user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError('user group `{}` does not exist'.format( - usergroupid)) + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError("user group `{}` does not exist".format(usergroupid)) old_values = user_group.get_api_data() try: ugm = UserGroupModel().add_user_to_group(user_group, user) success = True if ugm is not True else False - msg = 'added member `{}` to user group `{}`'.format( - user.username, user_group.users_group_name - ) - msg = msg if success else 'User is already in that group' + msg = "added member `{}` to user group `{}`".format(user.username, user_group.users_group_name) + msg = msg if success else "User is already in that group" if success: user_data = user.get_api_data() audit_logger.store_api( - 'user_group.edit.member.add', - action_data={'user': user_data, 'old_data': old_values}, - user=apiuser) + "user_group.edit.member.add", action_data={"user": user_data, "old_data": old_values}, user=apiuser + ) Session().commit() - return { - 'success': success, - 'msg': msg - } + return {"success": success, "msg": msg} except Exception: log.exception("Error occurred during adding a member to user group") raise JSONRPCError( - 'failed to add member to user group `{}`'.format( + "failed to add member to user group `{}`".format( user_group.users_group_name, ) ) @@ -573,40 +568,34 @@ def remove_user_from_user_group(request, apiuser, usergroupid, userid): user_group = get_user_group_or_error(usergroupid) if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") old_values = user_group.get_api_data() try: success = UserGroupModel().remove_user_from_group(user_group, user) - msg = 'removed member `{}` from user group `{}`'.format( - user.username, user_group.users_group_name - ) + msg = "removed member `{}` from user group `{}`".format(user.username, user_group.users_group_name) msg = msg if success else "User wasn't in group" if success: user_data = user.get_api_data() audit_logger.store_api( - 'user_group.edit.member.delete', - action_data={'user': user_data, 'old_data': old_values}, - user=apiuser) + "user_group.edit.member.delete", action_data={"user": user_data, "old_data": old_values}, user=apiuser + ) Session().commit() - return {'success': success, 'msg': msg} + return {"success": success, "msg": msg} except Exception: log.exception("Error occurred during removing an member from user group") raise JSONRPCError( - 'failed to remove member from user group `{}`'.format( + "failed to remove member from user group `{}`".format( user_group.users_group_name, ) ) @jsonrpc_method() -def grant_user_permission_to_user_group( - request, apiuser, usergroupid, userid, perm): +def grant_user_permission_to_user_group(request, apiuser, usergroupid, userid, perm): """ Set permissions for a user in a user group. @@ -635,50 +624,40 @@ def grant_user_permission_to_user_group( if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") user = get_user_or_error(userid) - perm = get_perm_or_error(perm, prefix='usergroup.') + perm = get_perm_or_error(perm, prefix="usergroup.") try: - changes = UserGroupModel().grant_user_permission( - user_group=user_group, user=user, perm=perm) + changes = UserGroupModel().grant_user_permission(user_group=user_group, user=user, perm=perm) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'user_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("user_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': - 'Granted perm: `{}` for user: `{}` in user group: `{}`'.format( - perm.permission_name, user.username, - user_group.users_group_name - ), - 'success': True + "msg": "Granted perm: `{}` for user: `{}` in user group: `{}`".format( + perm.permission_name, user.username, user_group.users_group_name + ), + "success": True, } except Exception: - log.exception("Error occurred during editing permissions " - "for user in user group") + log.exception("Error occurred during editing permissions for user in user group") raise JSONRPCError( - 'failed to edit permission for user: ' - '`%s` in user group: `%s`' % ( - userid, user_group.users_group_name)) + "failed to edit permission for user: `%s` in user group: `%s`" % (userid, user_group.users_group_name) + ) @jsonrpc_method() -def revoke_user_permission_from_user_group( - request, apiuser, usergroupid, userid): +def revoke_user_permission_from_user_group(request, apiuser, usergroupid, userid): """ Revoke a users permissions in a user group. @@ -707,45 +686,36 @@ def revoke_user_permission_from_user_group( if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{usergroupid}` does not exist') + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{usergroupid}` does not exist") user = get_user_or_error(userid) try: - changes = UserGroupModel().revoke_user_permission( - user_group=user_group, user=user) + changes = UserGroupModel().revoke_user_permission(user_group=user_group, user=user) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'user_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("user_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Revoked perm for user: `{}` in user group: `{}`'.format( - user.username, user_group.users_group_name - ), - 'success': True + "msg": "Revoked perm for user: `{}` in user group: `{}`".format(user.username, user_group.users_group_name), + "success": True, } except Exception: - log.exception("Error occurred during editing permissions " - "for user in user group") + log.exception("Error occurred during editing permissions for user in user group") raise JSONRPCError( - 'failed to edit permission for user: `%s` in user group: `%s`' - % (userid, user_group.users_group_name)) + "failed to edit permission for user: `%s` in user group: `%s`" % (userid, user_group.users_group_name) + ) @jsonrpc_method() -def grant_user_group_permission_to_user_group( - request, apiuser, usergroupid, sourceusergroupid, perm): +def grant_user_group_permission_to_user_group(request, apiuser, usergroupid, sourceusergroupid, perm): """ Give one user group permissions to another user group. @@ -773,62 +743,53 @@ def grant_user_group_permission_to_user_group( user_group = get_user_group_or_error(sourceusergroupid) target_user_group = get_user_group_or_error(usergroupid) - perm = get_perm_or_error(perm, prefix='usergroup.') + perm = get_perm_or_error(perm, prefix="usergroup.") if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, - user_group_name=target_user_group.users_group_name): - raise JSONRPCError( - f'to user group `{usergroupid}` does not exist') + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=target_user_group.users_group_name): + raise JSONRPCError(f"to user group `{usergroupid}` does not exist") # check if we have at least read permission for source user group ! - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{sourceusergroupid}` does not exist') + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{sourceusergroupid}` does not exist") try: changes = UserGroupModel().grant_user_group_permission( - target_user_group=target_user_group, - user_group=user_group, perm=perm) + target_user_group=target_user_group, user_group=user_group, perm=perm + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'user_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("user_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Granted perm: `%s` for user group: `%s` ' - 'in user group: `%s`' % ( - perm.permission_name, user_group.users_group_name, - target_user_group.users_group_name - ), - 'success': True + "msg": "Granted perm: `%s` for user group: `%s` " + "in user group: `%s`" + % (perm.permission_name, user_group.users_group_name, target_user_group.users_group_name), + "success": True, } except Exception: - log.exception("Error occurred during editing permissions " - "for user group in user group") + log.exception("Error occurred during editing permissions for user group in user group") raise JSONRPCError( - 'failed to edit permission for user group: `%s` in ' - 'user group: `%s`' % ( - sourceusergroupid, target_user_group.users_group_name - ) + "failed to edit permission for user group: `%s` in " + "user group: `%s`" % (sourceusergroupid, target_user_group.users_group_name) ) @jsonrpc_method() -def revoke_user_group_permission_from_user_group( - request, apiuser, usergroupid, sourceusergroupid): +def revoke_user_group_permission_from_user_group(request, apiuser, usergroupid, sourceusergroupid): """ Revoke the permissions that one user group has to another. @@ -857,49 +818,41 @@ def revoke_user_group_permission_from_user_group( if not has_superadmin_permission(apiuser): # check if we have admin permission for this user group ! - _perms = ('usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, - user_group_name=target_user_group.users_group_name): - raise JSONRPCError( - f'to user group `{usergroupid}` does not exist') + _perms = ("usergroup.admin",) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=target_user_group.users_group_name): + raise JSONRPCError(f"to user group `{usergroupid}` does not exist") # check if we have at least read permission # for the source user group ! - _perms = ('usergroup.read', 'usergroup.write', 'usergroup.admin',) - if not HasUserGroupPermissionAnyApi(*_perms)( - user=apiuser, user_group_name=user_group.users_group_name): - raise JSONRPCError( - f'user group `{sourceusergroupid}` does not exist') + _perms = ( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) + if not HasUserGroupPermissionAnyApi(*_perms)(user=apiuser, user_group_name=user_group.users_group_name): + raise JSONRPCError(f"user group `{sourceusergroupid}` does not exist") try: changes = UserGroupModel().revoke_user_group_permission( - target_user_group=target_user_group, user_group=user_group) + target_user_group=target_user_group, user_group=user_group + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_api( - 'user_group.edit.permissions', action_data=action_data, - user=apiuser) + audit_logger.store_api("user_group.edit.permissions", action_data=action_data, user=apiuser) Session().commit() PermissionModel().flush_user_permission_caches(changes) return { - 'msg': 'Revoked perm for user group: ' - '`%s` in user group: `%s`' % ( - user_group.users_group_name, - target_user_group.users_group_name - ), - 'success': True + "msg": "Revoked perm for user group: " + "`%s` in user group: `%s`" % (user_group.users_group_name, target_user_group.users_group_name), + "success": True, } except Exception: - log.exception("Error occurred during editing permissions " - "for user group in user group") + log.exception("Error occurred during editing permissions for user group in user group") raise JSONRPCError( - 'failed to edit permission for user group: ' - '`%s` in user group: `%s`' % ( - sourceusergroupid, target_user_group.users_group_name - ) + "failed to edit permission for user group: " + "`%s` in user group: `%s`" % (sourceusergroupid, target_user_group.users_group_name) ) diff --git a/rhodecode/apps/_base/__init__.py b/rhodecode/apps/_base/__init__.py index be7428bb..6881ee82 100644 --- a/rhodecode/apps/_base/__init__.py +++ b/rhodecode/apps/_base/__init__.py @@ -105,9 +105,9 @@ class TemplateArgs(StrictAttributeDict): class BaseAppView(object): DONT_CHECKOUT_VIEWS = ["channelstream_connect", "ops_ping"] - EXTRA_VIEWS_TO_IGNORE = ['login', 'register', 'logout'] - SETUP_2FA_VIEW = 'setup_2fa' - VERIFY_2FA_VIEW = 'check_2fa' + EXTRA_VIEWS_TO_IGNORE = ["login", "register", "logout"] + SETUP_2FA_VIEW = "setup_2fa" + VERIFY_2FA_VIEW = "check_2fa" def __init__(self, context, request): self.request = request @@ -123,23 +123,15 @@ class BaseAppView(object): self._rhodecode_user = request.user # auth user self._rhodecode_db_user = self._rhodecode_user.get_instance() self.user_data = self._rhodecode_db_user.user_data if self._rhodecode_db_user else {} - self._maybe_needs_password_change( - request.matched_route.name, self._rhodecode_db_user - ) - self._maybe_needs_2fa_configuration( - request.matched_route.name, self._rhodecode_db_user - ) - self._maybe_needs_2fa_check( - request.matched_route.name, self._rhodecode_db_user - ) + self._maybe_needs_password_change(request.matched_route.name, self._rhodecode_db_user) + self._maybe_needs_2fa_configuration(request.matched_route.name, self._rhodecode_db_user) + self._maybe_needs_2fa_check(request.matched_route.name, self._rhodecode_db_user) def _maybe_needs_password_change(self, view_name, user_obj): if view_name in self.DONT_CHECKOUT_VIEWS: return - log.debug( - "Checking if user %s needs password change on view %s", user_obj, view_name - ) + log.debug("Checking if user %s needs password change on view %s", user_obj, view_name) skip_user_views = [ "logout", @@ -230,21 +222,13 @@ class BaseAppView(object): c.is_delegated_admin = False if not c.auth_user.is_default and not c.is_super_admin: - c.can_create_repo = h.HasPermissionAny("hg.create.repository")( - user=self.request.user - ) + c.can_create_repo = h.HasPermissionAny("hg.create.repository")(user=self.request.user) repositories = c.auth_user.repositories_admin or c.can_create_repo - c.can_create_repo_group = h.HasPermissionAny("hg.repogroup.create.true")( - user=self.request.user - ) - repository_groups = ( - c.auth_user.repository_groups_admin or c.can_create_repo_group - ) + c.can_create_repo_group = h.HasPermissionAny("hg.repogroup.create.true")(user=self.request.user) + repository_groups = c.auth_user.repository_groups_admin or c.can_create_repo_group - c.can_create_user_group = h.HasPermissionAny("hg.usergroup.create.true")( - user=self.request.user - ) + c.can_create_user_group = h.HasPermissionAny("hg.usergroup.create.true")(user=self.request.user) user_groups = c.auth_user.user_groups_admin or c.can_create_user_group # delegated admin can create, or manage some objects c.is_delegated_admin = repositories or repository_groups or user_groups @@ -293,15 +277,9 @@ class RepoAppView(BaseAppView): _def_clone_uri_id = c.clone_uri_id_tmpl _def_clone_uri_ssh = c.clone_uri_ssh_tmpl - c.clone_repo_url = self.db_repo.clone_url( - user=username, uri_tmpl=_def_clone_uri - ) - c.clone_repo_url_id = self.db_repo.clone_url( - user=username, uri_tmpl=_def_clone_uri_id - ) - c.clone_repo_url_ssh = self.db_repo.clone_url( - uri_tmpl=_def_clone_uri_ssh, ssh=True - ) + c.clone_repo_url = self.db_repo.clone_url(user=username, uri_tmpl=_def_clone_uri) + c.clone_repo_url_id = self.db_repo.clone_url(user=username, uri_tmpl=_def_clone_uri_id) + c.clone_repo_url_ssh = self.db_repo.clone_url(uri_tmpl=_def_clone_uri_ssh, ssh=True) def _get_local_tmpl_context(self, include_app_defaults=True): _ = self.request.translate @@ -312,9 +290,7 @@ class RepoAppView(BaseAppView): c.repo_name = self.db_repo_name c.repository_pull_requests = self.db_repo_pull_requests c.repository_artifacts = self.db_repo_artifacts - c.repository_is_user_following = ScmModel().is_following_repo( - self.db_repo_name, self._rhodecode_user.user_id - ) + c.repository_is_user_following = ScmModel().is_following_repo(self.db_repo_name, self._rhodecode_user.user_id) self.path_filter = PathFilter(None) c.repository_requirements_missing = {} @@ -324,9 +300,7 @@ class RepoAppView(BaseAppView): # comparison to None since if it's an object __bool__ is expensive to # calculate if self.rhodecode_vcs_repo is not None: - path_perms = self.rhodecode_vcs_repo.get_path_permissions( - c.auth_user.username - ) + path_perms = self.rhodecode_vcs_repo.get_path_permissions(c.auth_user.username) self.path_filter = PathFilter(path_perms) except RepositoryRequirementError as e: c.repository_requirements_missing = {"error": str(e)} @@ -337,9 +311,7 @@ class RepoAppView(BaseAppView): if self.rhodecode_vcs_repo is None: # unable to fetch this repo as vcs instance, report back to user - log.debug( - "Repository was not found on filesystem, check if it exists or is not damaged" - ) + log.debug("Repository was not found on filesystem, check if it exists or is not damaged") h.flash( _( "The repository `%(repo_name)s` cannot be loaded in filesystem. " @@ -355,9 +327,7 @@ class RepoAppView(BaseAppView): # allow summary and edit repo on missing requirements return c - raise HTTPFound( - h.route_path("repo_summary", repo_name=self.db_repo_name) - ) + raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo_name)) else: # redirect if we don't show missing requirements raise HTTPFound(h.route_path("home")) @@ -406,15 +376,11 @@ class RepoAppView(BaseAppView): landing_commit_id = landing_commit.raw_id cache_namespace_uid = f"repo.{db_repo.repo_id}" - region = rc_cache.get_or_create_region( - "cache_repo", cache_namespace_uid, use_async_runner=False - ) + region = rc_cache.get_or_create_region("cache_repo", cache_namespace_uid, use_async_runner=False) start = time.time() @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) - def generate_repo_readme( - _repo_id, _commit_id, _repo_name, _readme_search_path, _renderer_type - ): + def generate_repo_readme(_repo_id, _commit_id, _repo_name, _readme_search_path, _renderer_type): _readme_data = None _readme_filename = None @@ -440,19 +406,13 @@ class RepoAppView(BaseAppView): ), } - _readme_data = self._render_readme_or_none( - commit, readme_node, relative_urls - ) + _readme_data = self._render_readme_or_none(commit, readme_node, relative_urls) _readme_filename = readme_node.str_path return _readme_data, _readme_filename readme_data, readme_filename = generate_repo_readme( - db_repo.repo_id, - landing_commit_id, - db_repo.repo_name, - path, - renderer_type + db_repo.repo_id, landing_commit_id, db_repo.repo_name, path, renderer_type ) compute_time = time.time() - start @@ -467,9 +427,7 @@ class RepoAppView(BaseAppView): log.debug("Found README file `%s` rendering...", readme_node.path) renderer = MarkupRenderer() try: - html_source = renderer.render( - readme_node.str_content, filename=readme_node.path - ) + html_source = renderer.render(readme_node.str_content, filename=readme_node.path) if relative_urls: return relative_links(html_source, relative_urls) return html_source @@ -511,9 +469,7 @@ class PathFilter(object): log.debug("Checking ACL permissions for PathFilter for `%s`", path) if self.permission_checker: has_access = path and self.permission_checker.has_access(path) - log.debug( - "ACL Permissions checker enabled, ACL Check has_access: %s", has_access - ) + log.debug("ACL Permissions checker enabled, ACL Check has_access: %s", has_access) return has_access log.debug("ACL permissions checker not enabled, skipping...") @@ -539,13 +495,9 @@ class PathFilter(object): else: return patchset, False - def render_patchset_filtered( - self, diffset, patchset, source_ref=None, target_ref=None - ): + def render_patchset_filtered(self, diffset, patchset, source_ref=None, target_ref=None): filtered_patchset, has_hidden_changes = self.filter_patchset(patchset) - result = diffset.render_patchset( - filtered_patchset, source_ref=source_ref, target_ref=target_ref - ) + result = diffset.render_patchset(filtered_patchset, source_ref=source_ref, target_ref=target_ref) result.has_hidden_changes = has_hidden_changes return result @@ -575,21 +527,9 @@ class RepoGroupAppView(BaseAppView): return c def _revoke_perms_on_yourself(self, form_result): - _updates = [ - u - for u in form_result["perm_updates"] - if self._rhodecode_user.user_id == int(u[0]) - ] - _additions = [ - u - for u in form_result["perm_additions"] - if self._rhodecode_user.user_id == int(u[0]) - ] - _deletions = [ - u - for u in form_result["perm_deletions"] - if self._rhodecode_user.user_id == int(u[0]) - ] + _updates = [u for u in form_result["perm_updates"] if self._rhodecode_user.user_id == int(u[0])] + _additions = [u for u in form_result["perm_additions"] if self._rhodecode_user.user_id == int(u[0])] + _deletions = [u for u in form_result["perm_deletions"] if self._rhodecode_user.user_id == int(u[0])] admin_perm = "group.admin" if ( _updates @@ -683,9 +623,7 @@ class BaseReferencesView(RepoAppView): data = [] for ref_name, commit_id in ref_items: - commit = self.rhodecode_vcs_repo.get_commit( - commit_id=commit_id, pre_load=pre_load - ) + commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id, pre_load=pre_load) closed = ref_name in closed_refs # TODO: johbo: Unify generation of reference links @@ -717,13 +655,9 @@ class BaseReferencesView(RepoAppView): "date": _render("date", commit.date), "date_raw": datetime_to_time(commit.date), "author": _render("author", commit.author), - "commit": _render( - "commit", commit.message, commit.raw_id, commit.idx - ), + "commit": _render("commit", commit.message, commit.raw_id, commit.idx), "commit_raw": commit.idx, - "compare": _render( - "compare", format_ref_id(ref_name, commit.raw_id) - ), + "compare": _render("compare", format_ref_id(ref_name, commit.raw_id)), } ) @@ -751,9 +685,7 @@ class RepoRoutePredicate(object): if repo_name_parts != repo_slugs: # short-skip if the repo-name doesn't follow slug rule - log.warning( - "repo_name: %s is different than slug %s", repo_name_parts, repo_slugs - ) + log.warning("repo_name: %s is different than slug %s", repo_name_parts, repo_slugs) return False repo_model = repo.RepoModel() @@ -769,9 +701,7 @@ class RepoRoutePredicate(object): return if db_repo.repo_state in [repo.Repository.STATE_PENDING]: - repo_creating_url = request.route_path( - "repo_creating", repo_name=db_repo.repo_name - ) + repo_creating_url = request.route_path("repo_creating", repo_name=db_repo.repo_name) raise HTTPFound(repo_creating_url) if by_name_match: @@ -821,9 +751,7 @@ class RepoForbidArchivedRoutePredicate(object): h.literal(_("Action not supported for archived repository.")), category="warning", ) - summary_url = request.route_path( - "repo_summary", repo_name=rhodecode_db_repo.repo_name - ) + summary_url = request.route_path("repo_summary", repo_name=rhodecode_db_repo.repo_name) raise HTTPFound(summary_url) return True @@ -878,9 +806,7 @@ class RepoGroupRoutePredicate(object): repo_group_name = info["match"]["repo_group_name"] repo_group_name_parts = repo_group_name.split("/") - repo_group_slugs = [ - x for x in [repo_name_slug(x) for x in repo_group_name_parts] - ] + repo_group_slugs = [x for x in [repo_name_slug(x) for x in repo_group_name_parts]] if repo_group_name_parts != repo_group_slugs: # short-skip if the repo-name doesn't follow slug rule log.warning( @@ -976,9 +902,7 @@ class UserRouteWithDefaultPredicate(UserRoutePredicateBase): def includeme(config): config.add_route_predicate("repo_route", RepoRoutePredicate) config.add_route_predicate("repo_accepted_types", RepoTypeRoutePredicate) - config.add_route_predicate( - "repo_forbid_when_archived", RepoForbidArchivedRoutePredicate - ) + config.add_route_predicate("repo_forbid_when_archived", RepoForbidArchivedRoutePredicate) config.add_route_predicate("repo_group_route", RepoGroupRoutePredicate) config.add_route_predicate("user_group_route", UserGroupRoutePredicate) config.add_route_predicate("user_route_with_default", UserRouteWithDefaultPredicate) diff --git a/rhodecode/apps/_base/interfaces.py b/rhodecode/apps/_base/interfaces.py index 373f59fc..cb99746e 100644 --- a/rhodecode/apps/_base/interfaces.py +++ b/rhodecode/apps/_base/interfaces.py @@ -24,4 +24,5 @@ class IAdminNavigationRegistry(Interface): Interface for the admin navigation registry. Currently this is only used to register and retrieve it via pyramids registry. """ + pass diff --git a/rhodecode/apps/_base/navigation.py b/rhodecode/apps/_base/navigation.py index 0dcb7a75..a9add214 100644 --- a/rhodecode/apps/_base/navigation.py +++ b/rhodecode/apps/_base/navigation.py @@ -1,5 +1,4 @@ - -import dataclasses# Copyright (C) 2016-2024 RhodeCode GmbH +import dataclasses # Copyright (C) 2016-2024 RhodeCode GmbH # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License, version 3 @@ -71,39 +70,28 @@ class NavEntry(object): @implementer(IAdminNavigationRegistry) class NavigationRegistry(object): - _base_entries = [ - NavEntry('global', _('Global'), - 'admin_settings_global'), - NavEntry('vcs', _('VCS'), - 'admin_settings_vcs'), - NavEntry('visual', _('Visual'), - 'admin_settings_visual'), - NavEntry('mapping', _('Remap and Rescan'), - 'admin_settings_mapping'), - NavEntry('issuetracker', _('Issue Tracker'), - 'admin_settings_issuetracker'), - NavEntry('email', _('Email'), - 'admin_settings_email'), - NavEntry('hooks', _('Hooks'), - 'admin_settings_hooks'), - NavEntry('search', _('Full Text Search'), - 'admin_settings_search'), - NavEntry('system', _('System Info'), - 'admin_settings_system'), - NavEntry('exceptions', _('Exceptions Tracker'), - 'admin_settings_exception_tracker', - active_list=['exceptions', 'exceptions_browse']), - NavEntry('process_management', _('Processes'), - 'admin_settings_process_management'), - NavEntry('sessions', _('User Sessions'), - 'admin_settings_sessions'), - NavEntry('open_source', _('Open Source Licenses'), - 'admin_settings_open_source'), + NavEntry("global", _("Global"), "admin_settings_global"), + NavEntry("vcs", _("VCS"), "admin_settings_vcs"), + NavEntry("visual", _("Visual"), "admin_settings_visual"), + NavEntry("mapping", _("Remap and Rescan"), "admin_settings_mapping"), + NavEntry("issuetracker", _("Issue Tracker"), "admin_settings_issuetracker"), + NavEntry("email", _("Email"), "admin_settings_email"), + NavEntry("hooks", _("Hooks"), "admin_settings_hooks"), + NavEntry("search", _("Full Text Search"), "admin_settings_search"), + NavEntry("system", _("System Info"), "admin_settings_system"), + NavEntry( + "exceptions", + _("Exceptions Tracker"), + "admin_settings_exception_tracker", + active_list=["exceptions", "exceptions_browse"], + ), + NavEntry("process_management", _("Processes"), "admin_settings_process_management"), + NavEntry("sessions", _("User Sessions"), "admin_settings_sessions"), + NavEntry("open_source", _("Open Source Licenses"), "admin_settings_open_source"), ] - _labs_entry = NavEntry('labs', _('Labs'), - 'admin_settings_labs') + _labs_entry = NavEntry("labs", _("Labs"), "admin_settings_labs") def __init__(self, labs_active=False): self._registered_entries = collections.OrderedDict() @@ -118,8 +106,7 @@ class NavigationRegistry(object): def get_navlist(self, request): nav_list = [ - NavListEntry(i.key, i.get_localized_name(request), - i.generate_url(request), i.active_list) + NavListEntry(i.key, i.get_localized_name(request), i.generate_url(request), i.active_list) for i in self._registered_entries.values() ] return nav_list @@ -144,8 +131,7 @@ def navigation_list(request): def includeme(config): # Create admin navigation registry and add it to the pyramid registry. settings = config.get_settings() - labs_active = str2bool(settings.get('labs_settings_active', False)) + labs_active = str2bool(settings.get("labs_settings_active", False)) navigation_registry_instance = NavigationRegistry(labs_active=labs_active) config.registry.registerUtility(navigation_registry_instance) - log.debug('Created new navigation instance, %s', navigation_registry_instance) - + log.debug("Created new navigation instance, %s", navigation_registry_instance) diff --git a/rhodecode/apps/_base/subscribers.py b/rhodecode/apps/_base/subscribers.py index f15550e6..ed9034ab 100644 --- a/rhodecode/apps/_base/subscribers.py +++ b/rhodecode/apps/_base/subscribers.py @@ -26,10 +26,10 @@ log = logging.getLogger(__name__) # names of namespaces used for different permission related cached # during flush operation we need to take care of all those cache_namespaces = [ - f'cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}', - f'cache_user_repo_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}', - f'cache_user_user_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}', - f'cache_user_repo_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}' + f"cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}", + f"cache_user_repo_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}", + f"cache_user_user_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}", + f"cache_user_repo_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{{}}", ] @@ -44,9 +44,10 @@ def trigger_user_permission_flush(event): for user_id in affected_user_ids: for cache_namespace_uid_tmpl in cache_namespaces: cache_namespace_uid = cache_namespace_uid_tmpl.format(user_id) - del_keys = rc_cache.clear_cache_namespace('cache_perms', cache_namespace_uid, method=rc_cache.CLEAR_DELETE) - log.debug('Invalidated %s cache keys for user_id: %s and namespace %s', - del_keys, user_id, cache_namespace_uid) + del_keys = rc_cache.clear_cache_namespace("cache_perms", cache_namespace_uid, method=rc_cache.CLEAR_DELETE) + log.debug( + "Invalidated %s cache keys for user_id: %s and namespace %s", del_keys, user_id, cache_namespace_uid + ) def includeme(config): diff --git a/rhodecode/apps/admin/__init__.py b/rhodecode/apps/admin/__init__.py index 838e1065..88ce4960 100644 --- a/rhodecode/apps/admin/__init__.py +++ b/rhodecode/apps/admin/__init__.py @@ -35,7 +35,7 @@ def admin_routes(config): from rhodecode.apps.admin.views.open_source_licenses import OpenSourceLicensesAdminSettingsView from rhodecode.apps.admin.views.permissions import AdminPermissionsView from rhodecode.apps.admin.views.process_management import AdminProcessManagementView - from rhodecode.apps.admin.views.repo_groups import AdminRepoGroupsView + from rhodecode.apps.admin.views.repo_groups import AdminRepoGroupsView from rhodecode.apps.admin.views.repositories import AdminReposView from rhodecode.apps.admin.views.sessions import AdminSessionSettingsView from rhodecode.apps.admin.views.settings import AdminSettingsView @@ -47,1049 +47,1034 @@ def admin_routes(config): # Security EE feature - config.add_route( - 'admin_security', - pattern='/security') + config.add_route("admin_security", pattern="/security") config.add_view( AdminSecurityView, - attr='security', - route_name='admin_security', request_method='GET', - renderer='rhodecode:templates/admin/security/security.mako') + attr="security", + route_name="admin_security", + request_method="GET", + renderer="rhodecode:templates/admin/security/security.mako", + ) - config.add_route( - name='admin_security_update', - pattern='/security/update') + config.add_route(name="admin_security_update", pattern="/security/update") config.add_view( AdminSecurityView, - attr='security_update', - route_name='admin_security_update', request_method='POST', - renderer='rhodecode:templates/admin/security/security.mako') + attr="security_update", + route_name="admin_security_update", + request_method="POST", + renderer="rhodecode:templates/admin/security/security.mako", + ) config.add_route( - name='admin_security_modify_allowed_vcs_client_versions', - pattern=ADMIN_PREFIX + '/security/modify/allowed_vcs_client_versions') + name="admin_security_modify_allowed_vcs_client_versions", + pattern=ADMIN_PREFIX + "/security/modify/allowed_vcs_client_versions", + ) config.add_view( AdminSecurityView, - attr='vcs_whitelisted_client_versions_edit', - route_name='admin_security_modify_allowed_vcs_client_versions', request_method=('GET', 'POST'), - renderer='rhodecode:templates/admin/security/edit_allowed_vcs_client_versions.mako') + attr="vcs_whitelisted_client_versions_edit", + route_name="admin_security_modify_allowed_vcs_client_versions", + request_method=("GET", "POST"), + renderer="rhodecode:templates/admin/security/edit_allowed_vcs_client_versions.mako", + ) - - config.add_route( - name='admin_audit_logs', - pattern='/audit_logs') + config.add_route(name="admin_audit_logs", pattern="/audit_logs") config.add_view( AdminAuditLogsView, - attr='admin_audit_logs', - route_name='admin_audit_logs', request_method='GET', - renderer='rhodecode:templates/admin/admin_audit_logs.mako') + attr="admin_audit_logs", + route_name="admin_audit_logs", + request_method="GET", + renderer="rhodecode:templates/admin/admin_audit_logs.mako", + ) - config.add_route( - name='admin_audit_log_entry', - pattern='/audit_logs/{audit_log_id}') + config.add_route(name="admin_audit_log_entry", pattern="/audit_logs/{audit_log_id}") config.add_view( AdminAuditLogsView, - attr='admin_audit_log_entry', - route_name='admin_audit_log_entry', request_method='GET', - renderer='rhodecode:templates/admin/admin_audit_log_entry.mako') + attr="admin_audit_log_entry", + route_name="admin_audit_log_entry", + request_method="GET", + renderer="rhodecode:templates/admin/admin_audit_log_entry.mako", + ) # Artifacts EE feature - config.add_route( - 'admin_artifacts', - pattern=ADMIN_PREFIX + '/artifacts') - config.add_route( - 'admin_artifacts_show_all', - pattern=ADMIN_PREFIX + '/artifacts') + config.add_route("admin_artifacts", pattern=ADMIN_PREFIX + "/artifacts") + config.add_route("admin_artifacts_show_all", pattern=ADMIN_PREFIX + "/artifacts") config.add_view( AdminArtifactsView, - attr='artifacts', - route_name='admin_artifacts', request_method='GET', - renderer='rhodecode:templates/admin/artifacts/artifacts.mako') + attr="artifacts", + route_name="admin_artifacts", + request_method="GET", + renderer="rhodecode:templates/admin/artifacts/artifacts.mako", + ) config.add_view( AdminArtifactsView, - attr='artifacts', - route_name='admin_artifacts_show_all', request_method='GET', - renderer='rhodecode:templates/admin/artifacts/artifacts.mako') + attr="artifacts", + route_name="admin_artifacts_show_all", + request_method="GET", + renderer="rhodecode:templates/admin/artifacts/artifacts.mako", + ) # EE views - config.add_route( - name='admin_artifacts_show_info', - pattern=ADMIN_PREFIX + '/artifacts/{uid}') - config.add_route( - name='admin_artifacts_delete', - pattern=ADMIN_PREFIX + '/artifacts/{uid}/delete') - config.add_route( - name='admin_artifacts_update', - pattern=ADMIN_PREFIX + '/artifacts/{uid}/update') + config.add_route(name="admin_artifacts_show_info", pattern=ADMIN_PREFIX + "/artifacts/{uid}") + config.add_route(name="admin_artifacts_delete", pattern=ADMIN_PREFIX + "/artifacts/{uid}/delete") + config.add_route(name="admin_artifacts_update", pattern=ADMIN_PREFIX + "/artifacts/{uid}/update") # Automation EE feature - config.add_route( - 'admin_automation', - pattern=ADMIN_PREFIX + '/automation') + config.add_route("admin_automation", pattern=ADMIN_PREFIX + "/automation") config.add_view( AdminAutomationView, - attr='automation', - route_name='admin_automation', request_method='GET', - renderer='rhodecode:templates/admin/automation/automation.mako') + attr="automation", + route_name="admin_automation", + request_method="GET", + renderer="rhodecode:templates/admin/automation/automation.mako", + ) # Scheduler EE feature - config.add_route( - 'admin_scheduler', - pattern=ADMIN_PREFIX + '/scheduler') + config.add_route("admin_scheduler", pattern=ADMIN_PREFIX + "/scheduler") config.add_view( AdminSchedulerView, - attr='scheduler', - route_name='admin_scheduler', request_method='GET', - renderer='rhodecode:templates/admin/scheduler/scheduler.mako') + attr="scheduler", + route_name="admin_scheduler", + request_method="GET", + renderer="rhodecode:templates/admin/scheduler/scheduler.mako", + ) - config.add_route( - name='admin_settings_open_source', - pattern='/settings/open_source') + config.add_route(name="admin_settings_open_source", pattern="/settings/open_source") config.add_view( OpenSourceLicensesAdminSettingsView, - attr='open_source_licenses', - route_name='admin_settings_open_source', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="open_source_licenses", + route_name="admin_settings_open_source", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_vcs_svn_generate_cfg', - pattern='/settings/vcs/svn_generate_cfg') + config.add_route(name="admin_settings_vcs_svn_generate_cfg", pattern="/settings/vcs/svn_generate_cfg") config.add_view( AdminSvnConfigView, - attr='vcs_svn_generate_config', - route_name='admin_settings_vcs_svn_generate_cfg', - request_method='POST', renderer='json') + attr="vcs_svn_generate_config", + route_name="admin_settings_vcs_svn_generate_cfg", + request_method="POST", + renderer="json", + ) - config.add_route( - name='admin_settings_system', - pattern='/settings/system') + config.add_route(name="admin_settings_system", pattern="/settings/system") config.add_view( AdminSystemInfoSettingsView, - attr='settings_system_info', - route_name='admin_settings_system', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_system_info", + route_name="admin_settings_system", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_system_update', - pattern='/settings/system/updates') + config.add_route(name="admin_settings_system_update", pattern="/settings/system/updates") config.add_view( AdminSystemInfoSettingsView, - attr='settings_system_info_check_update', - route_name='admin_settings_system_update', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings_system_update.mako') + attr="settings_system_info_check_update", + route_name="admin_settings_system_update", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings_system_update.mako", + ) - config.add_route( - name='admin_settings_exception_tracker', - pattern='/settings/exceptions') + config.add_route(name="admin_settings_exception_tracker", pattern="/settings/exceptions") config.add_view( ExceptionsTrackerView, - attr='browse_exceptions', - route_name='admin_settings_exception_tracker', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="browse_exceptions", + route_name="admin_settings_exception_tracker", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_exception_tracker_delete_all', - pattern='/settings/exceptions_delete_all') + config.add_route(name="admin_settings_exception_tracker_delete_all", pattern="/settings/exceptions_delete_all") config.add_view( ExceptionsTrackerView, - attr='exception_delete_all', - route_name='admin_settings_exception_tracker_delete_all', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="exception_delete_all", + route_name="admin_settings_exception_tracker_delete_all", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_exception_tracker_show', - pattern='/settings/exceptions/{exception_id}') + config.add_route(name="admin_settings_exception_tracker_show", pattern="/settings/exceptions/{exception_id}") config.add_view( ExceptionsTrackerView, - attr='exception_show', - route_name='admin_settings_exception_tracker_show', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="exception_show", + route_name="admin_settings_exception_tracker_show", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) config.add_route( - name='admin_settings_exception_tracker_delete', - pattern='/settings/exceptions/{exception_id}/delete') + name="admin_settings_exception_tracker_delete", pattern="/settings/exceptions/{exception_id}/delete" + ) config.add_view( ExceptionsTrackerView, - attr='exception_delete', - route_name='admin_settings_exception_tracker_delete', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="exception_delete", + route_name="admin_settings_exception_tracker_delete", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_sessions', - pattern='/settings/sessions') + config.add_route(name="admin_settings_sessions", pattern="/settings/sessions") config.add_view( AdminSessionSettingsView, - attr='settings_sessions', - route_name='admin_settings_sessions', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_sessions", + route_name="admin_settings_sessions", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_sessions_cleanup', - pattern='/settings/sessions/cleanup') + config.add_route(name="admin_settings_sessions_cleanup", pattern="/settings/sessions/cleanup") config.add_view( AdminSessionSettingsView, - attr='settings_sessions_cleanup', - route_name='admin_settings_sessions_cleanup', request_method='POST') + attr="settings_sessions_cleanup", + route_name="admin_settings_sessions_cleanup", + request_method="POST", + ) - config.add_route( - name='admin_settings_process_management', - pattern='/settings/process_management') + config.add_route(name="admin_settings_process_management", pattern="/settings/process_management") config.add_view( AdminProcessManagementView, - attr='process_management', - route_name='admin_settings_process_management', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="process_management", + route_name="admin_settings_process_management", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_process_management_data', - pattern='/settings/process_management/data') + config.add_route(name="admin_settings_process_management_data", pattern="/settings/process_management/data") config.add_view( AdminProcessManagementView, - attr='process_management_data', - route_name='admin_settings_process_management_data', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings_process_management_data.mako') + attr="process_management_data", + route_name="admin_settings_process_management_data", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings_process_management_data.mako", + ) - config.add_route( - name='admin_settings_process_management_signal', - pattern='/settings/process_management/signal') + config.add_route(name="admin_settings_process_management_signal", pattern="/settings/process_management/signal") config.add_view( AdminProcessManagementView, - attr='process_management_signal', - route_name='admin_settings_process_management_signal', - request_method='POST', renderer='json_ext') + attr="process_management_signal", + route_name="admin_settings_process_management_signal", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='admin_settings_process_management_master_signal', - pattern='/settings/process_management/master_signal') + name="admin_settings_process_management_master_signal", pattern="/settings/process_management/master_signal" + ) config.add_view( AdminProcessManagementView, - attr='process_management_master_signal', - route_name='admin_settings_process_management_master_signal', - request_method='POST', renderer='json_ext') + attr="process_management_master_signal", + route_name="admin_settings_process_management_master_signal", + request_method="POST", + renderer="json_ext", + ) # default settings - config.add_route( - name='admin_defaults_repositories', - pattern='/defaults/repositories') + config.add_route(name="admin_defaults_repositories", pattern="/defaults/repositories") config.add_view( AdminDefaultSettingsView, - attr='defaults_repository_show', - route_name='admin_defaults_repositories', request_method='GET', - renderer='rhodecode:templates/admin/defaults/defaults.mako') + attr="defaults_repository_show", + route_name="admin_defaults_repositories", + request_method="GET", + renderer="rhodecode:templates/admin/defaults/defaults.mako", + ) - config.add_route( - name='admin_defaults_repositories_update', - pattern='/defaults/repositories/update') + config.add_route(name="admin_defaults_repositories_update", pattern="/defaults/repositories/update") config.add_view( AdminDefaultSettingsView, - attr='defaults_repository_update', - route_name='admin_defaults_repositories_update', request_method='POST', - renderer='rhodecode:templates/admin/defaults/defaults.mako') + attr="defaults_repository_update", + route_name="admin_defaults_repositories_update", + request_method="POST", + renderer="rhodecode:templates/admin/defaults/defaults.mako", + ) # admin settings - config.add_route( - name='admin_settings', - pattern='/settings') + config.add_route(name="admin_settings", pattern="/settings") config.add_view( AdminSettingsView, - attr='settings_global', - route_name='admin_settings', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_global", + route_name="admin_settings", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_update', - pattern='/settings/update') + config.add_route(name="admin_settings_update", pattern="/settings/update") config.add_view( AdminSettingsView, - attr='settings_global_update', - route_name='admin_settings_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_global_update", + route_name="admin_settings_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_global', - pattern='/settings/global') + config.add_route(name="admin_settings_global", pattern="/settings/global") config.add_view( AdminSettingsView, - attr='settings_global', - route_name='admin_settings_global', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_global", + route_name="admin_settings_global", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_global_update', - pattern='/settings/global/update') + config.add_route(name="admin_settings_global_update", pattern="/settings/global/update") config.add_view( AdminSettingsView, - attr='settings_global_update', - route_name='admin_settings_global_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_global_update", + route_name="admin_settings_global_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_vcs', - pattern='/settings/vcs') + config.add_route(name="admin_settings_vcs", pattern="/settings/vcs") config.add_view( AdminSettingsView, - attr='settings_vcs', - route_name='admin_settings_vcs', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_vcs", + route_name="admin_settings_vcs", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_vcs_update', - pattern='/settings/vcs/update') + config.add_route(name="admin_settings_vcs_update", pattern="/settings/vcs/update") config.add_view( AdminSettingsView, - attr='settings_vcs_update', - route_name='admin_settings_vcs_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_vcs_update", + route_name="admin_settings_vcs_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_vcs_svn_pattern_delete', - pattern='/settings/vcs/svn_pattern_delete') + config.add_route(name="admin_settings_vcs_svn_pattern_delete", pattern="/settings/vcs/svn_pattern_delete") config.add_view( AdminSettingsView, - attr='settings_vcs_delete_svn_pattern', - route_name='admin_settings_vcs_svn_pattern_delete', request_method='POST', - renderer='json_ext', xhr=True) + attr="settings_vcs_delete_svn_pattern", + route_name="admin_settings_vcs_svn_pattern_delete", + request_method="POST", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='admin_settings_mapping', - pattern='/settings/mapping') + config.add_route(name="admin_settings_mapping", pattern="/settings/mapping") config.add_view( AdminSettingsView, - attr='settings_mapping', - route_name='admin_settings_mapping', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_mapping", + route_name="admin_settings_mapping", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_mapping_create', - pattern='/settings/mapping/create') + config.add_route(name="admin_settings_mapping_create", pattern="/settings/mapping/create") config.add_view( AdminSettingsView, - attr='settings_mapping_create', - route_name='admin_settings_mapping_create', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_mapping_create", + route_name="admin_settings_mapping_create", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_mapping_cleanup', - pattern='/settings/mapping/cleanup') + config.add_route(name="admin_settings_mapping_cleanup", pattern="/settings/mapping/cleanup") config.add_view( AdminSettingsView, - attr='settings_mapping_cleanup', - route_name='admin_settings_mapping_cleanup', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_mapping_cleanup", + route_name="admin_settings_mapping_cleanup", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_visual', - pattern='/settings/visual') + config.add_route(name="admin_settings_visual", pattern="/settings/visual") config.add_view( AdminSettingsView, - attr='settings_visual', - route_name='admin_settings_visual', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_visual", + route_name="admin_settings_visual", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_visual_update', - pattern='/settings/visual/update') + config.add_route(name="admin_settings_visual_update", pattern="/settings/visual/update") config.add_view( AdminSettingsView, - attr='settings_visual_update', - route_name='admin_settings_visual_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_visual_update", + route_name="admin_settings_visual_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_issuetracker', - pattern='/settings/issue-tracker') + config.add_route(name="admin_settings_issuetracker", pattern="/settings/issue-tracker") config.add_view( AdminSettingsView, - attr='settings_issuetracker', - route_name='admin_settings_issuetracker', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_issuetracker", + route_name="admin_settings_issuetracker", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_issuetracker_update', - pattern='/settings/issue-tracker/update') + config.add_route(name="admin_settings_issuetracker_update", pattern="/settings/issue-tracker/update") config.add_view( AdminSettingsView, - attr='settings_issuetracker_update', - route_name='admin_settings_issuetracker_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_issuetracker_update", + route_name="admin_settings_issuetracker_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_issuetracker_test', - pattern='/settings/issue-tracker/test') + config.add_route(name="admin_settings_issuetracker_test", pattern="/settings/issue-tracker/test") config.add_view( AdminSettingsView, - attr='settings_issuetracker_test', - route_name='admin_settings_issuetracker_test', request_method='POST', - renderer='string', xhr=True) + attr="settings_issuetracker_test", + route_name="admin_settings_issuetracker_test", + request_method="POST", + renderer="string", + xhr=True, + ) - config.add_route( - name='admin_settings_issuetracker_delete', - pattern='/settings/issue-tracker/delete') + config.add_route(name="admin_settings_issuetracker_delete", pattern="/settings/issue-tracker/delete") config.add_view( AdminSettingsView, - attr='settings_issuetracker_delete', - route_name='admin_settings_issuetracker_delete', request_method='POST', - renderer='json_ext', xhr=True) + attr="settings_issuetracker_delete", + route_name="admin_settings_issuetracker_delete", + request_method="POST", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='admin_settings_email', - pattern='/settings/email') + config.add_route(name="admin_settings_email", pattern="/settings/email") config.add_view( AdminSettingsView, - attr='settings_email', - route_name='admin_settings_email', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_email", + route_name="admin_settings_email", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_email_update', - pattern='/settings/email/update') + config.add_route(name="admin_settings_email_update", pattern="/settings/email/update") config.add_view( AdminSettingsView, - attr='settings_email_update', - route_name='admin_settings_email_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_email_update", + route_name="admin_settings_email_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_hooks', - pattern='/settings/hooks') + config.add_route(name="admin_settings_hooks", pattern="/settings/hooks") config.add_view( AdminSettingsView, - attr='settings_hooks', - route_name='admin_settings_hooks', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_hooks", + route_name="admin_settings_hooks", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_hooks_update', - pattern='/settings/hooks/update') + config.add_route(name="admin_settings_hooks_update", pattern="/settings/hooks/update") config.add_view( AdminSettingsView, - attr='settings_hooks_update', - route_name='admin_settings_hooks_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_hooks_update", + route_name="admin_settings_hooks_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_hooks_delete', - pattern='/settings/hooks/delete') + config.add_route(name="admin_settings_hooks_delete", pattern="/settings/hooks/delete") config.add_view( AdminSettingsView, - attr='settings_hooks_update', - route_name='admin_settings_hooks_delete', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_hooks_update", + route_name="admin_settings_hooks_delete", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_search', - pattern='/settings/search') + config.add_route(name="admin_settings_search", pattern="/settings/search") config.add_view( AdminSettingsView, - attr='settings_search', - route_name='admin_settings_search', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_search", + route_name="admin_settings_search", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_labs', - pattern='/settings/labs') + config.add_route(name="admin_settings_labs", pattern="/settings/labs") config.add_view( AdminSettingsView, - attr='settings_labs', - route_name='admin_settings_labs', request_method='GET', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_labs", + route_name="admin_settings_labs", + request_method="GET", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) - config.add_route( - name='admin_settings_labs_update', - pattern='/settings/labs/update') + config.add_route(name="admin_settings_labs_update", pattern="/settings/labs/update") config.add_view( AdminSettingsView, - attr='settings_labs_update', - route_name='admin_settings_labs_update', request_method='POST', - renderer='rhodecode:templates/admin/settings/settings.mako') + attr="settings_labs_update", + route_name="admin_settings_labs_update", + request_method="POST", + renderer="rhodecode:templates/admin/settings/settings.mako", + ) # global permissions - config.add_route( - name='admin_permissions_application', - pattern='/permissions/application') + config.add_route(name="admin_permissions_application", pattern="/permissions/application") config.add_view( AdminPermissionsView, - attr='permissions_application', - route_name='admin_permissions_application', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_application", + route_name="admin_permissions_application", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_application_update', - pattern='/permissions/application/update') + config.add_route(name="admin_permissions_application_update", pattern="/permissions/application/update") config.add_view( AdminPermissionsView, - attr='permissions_application_update', - route_name='admin_permissions_application_update', request_method='POST', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_application_update", + route_name="admin_permissions_application_update", + request_method="POST", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_global', - pattern='/permissions/global') + config.add_route(name="admin_permissions_global", pattern="/permissions/global") config.add_view( AdminPermissionsView, - attr='permissions_global', - route_name='admin_permissions_global', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') - - config.add_route( - name='admin_permissions_global_update', - pattern='/permissions/global/update') - config.add_view( - AdminPermissionsView, - attr='permissions_global_update', - route_name='admin_permissions_global_update', request_method='POST', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_global", + route_name="admin_permissions_global", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_object', - pattern='/permissions/object') + config.add_route(name="admin_permissions_global_update", pattern="/permissions/global/update") config.add_view( AdminPermissionsView, - attr='permissions_objects', - route_name='admin_permissions_object', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_global_update", + route_name="admin_permissions_global_update", + request_method="POST", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_object_update', - pattern='/permissions/object/update') + config.add_route(name="admin_permissions_object", pattern="/permissions/object") config.add_view( AdminPermissionsView, - attr='permissions_objects_update', - route_name='admin_permissions_object_update', request_method='POST', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_objects", + route_name="admin_permissions_object", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) + + config.add_route(name="admin_permissions_object_update", pattern="/permissions/object/update") + config.add_view( + AdminPermissionsView, + attr="permissions_objects_update", + route_name="admin_permissions_object_update", + request_method="POST", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) # Branch perms EE feature - config.add_route( - name='admin_permissions_branch', - pattern='/permissions/branch') + config.add_route(name="admin_permissions_branch", pattern="/permissions/branch") config.add_view( AdminPermissionsView, - attr='permissions_branch', - route_name='admin_permissions_branch', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_branch", + route_name="admin_permissions_branch", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_ips', - pattern='/permissions/ips') + config.add_route(name="admin_permissions_ips", pattern="/permissions/ips") config.add_view( AdminPermissionsView, - attr='permissions_ips', - route_name='admin_permissions_ips', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_ips", + route_name="admin_permissions_ips", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_overview', - pattern='/permissions/overview') + config.add_route(name="admin_permissions_overview", pattern="/permissions/overview") config.add_view( AdminPermissionsView, - attr='permissions_overview', - route_name='admin_permissions_overview', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="permissions_overview", + route_name="admin_permissions_overview", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_auth_token_access', - pattern='/permissions/auth_token_access') + config.add_route(name="admin_permissions_auth_token_access", pattern="/permissions/auth_token_access") config.add_view( AdminPermissionsView, - attr='auth_token_access', - route_name='admin_permissions_auth_token_access', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="auth_token_access", + route_name="admin_permissions_auth_token_access", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_ssh_keys', - pattern='/permissions/ssh_keys') + config.add_route(name="admin_permissions_ssh_keys", pattern="/permissions/ssh_keys") config.add_view( AdminPermissionsView, - attr='ssh_keys', - route_name='admin_permissions_ssh_keys', request_method='GET', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="ssh_keys", + route_name="admin_permissions_ssh_keys", + request_method="GET", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) - config.add_route( - name='admin_permissions_ssh_keys_data', - pattern='/permissions/ssh_keys/data') + config.add_route(name="admin_permissions_ssh_keys_data", pattern="/permissions/ssh_keys/data") config.add_view( AdminPermissionsView, - attr='ssh_keys_data', - route_name='admin_permissions_ssh_keys_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="ssh_keys_data", + route_name="admin_permissions_ssh_keys_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='admin_permissions_ssh_keys_update', - pattern='/permissions/ssh_keys/update') + config.add_route(name="admin_permissions_ssh_keys_update", pattern="/permissions/ssh_keys/update") config.add_view( AdminPermissionsView, - attr='ssh_keys_update', - route_name='admin_permissions_ssh_keys_update', request_method='POST', - renderer='rhodecode:templates/admin/permissions/permissions.mako') + attr="ssh_keys_update", + route_name="admin_permissions_ssh_keys_update", + request_method="POST", + renderer="rhodecode:templates/admin/permissions/permissions.mako", + ) # users admin - config.add_route( - name='users', - pattern='/users') + config.add_route(name="users", pattern="/users") config.add_view( AdminUsersView, - attr='users_list', - route_name='users', request_method='GET', - renderer='rhodecode:templates/admin/users/users.mako') + attr="users_list", + route_name="users", + request_method="GET", + renderer="rhodecode:templates/admin/users/users.mako", + ) - config.add_route( - name='users_data', - pattern='/users_data') + config.add_route(name="users_data", pattern="/users_data") config.add_view( AdminUsersView, - attr='users_list_data', + attr="users_list_data", # renderer defined below - route_name='users_data', request_method='GET', - renderer='json_ext', xhr=True) + route_name="users_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='users_create', - pattern='/users/create') + config.add_route(name="users_create", pattern="/users/create") config.add_view( AdminUsersView, - attr='users_create', - route_name='users_create', request_method='POST', - renderer='rhodecode:templates/admin/users/user_add.mako') + attr="users_create", + route_name="users_create", + request_method="POST", + renderer="rhodecode:templates/admin/users/user_add.mako", + ) - config.add_route( - name='users_new', - pattern='/users/new') + config.add_route(name="users_new", pattern="/users/new") config.add_view( AdminUsersView, - attr='users_new', - route_name='users_new', request_method='GET', - renderer='rhodecode:templates/admin/users/user_add.mako') + attr="users_new", + route_name="users_new", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_add.mako", + ) # user management - config.add_route( - name='user_edit', - pattern=r'/users/{user_id:\d+}/edit', - user_route=True) + config.add_route(name="user_edit", pattern=r"/users/{user_id:\d+}/edit", user_route=True) config.add_view( UsersView, - attr='user_edit', - route_name='user_edit', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_edit", + route_name="user_edit", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) + + config.add_route(name="user_edit_advanced", pattern=r"/users/{user_id:\d+}/edit/advanced", user_route=True) + config.add_view( + UsersView, + attr="user_edit_advanced", + route_name="user_edit_advanced", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='user_edit_advanced', - pattern=r'/users/{user_id:\d+}/edit/advanced', - user_route=True) + name="user_edit_global_perms", pattern=r"/users/{user_id:\d+}/edit/global_permissions", user_route=True + ) config.add_view( UsersView, - attr='user_edit_advanced', - route_name='user_edit_advanced', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_edit_global_perms", + route_name="user_edit_global_perms", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='user_edit_global_perms', - pattern=r'/users/{user_id:\d+}/edit/global_permissions', - user_route=True) + name="user_edit_global_perms_update", + pattern=r"/users/{user_id:\d+}/edit/global_permissions/update", + user_route=True, + ) config.add_view( UsersView, - attr='user_edit_global_perms', - route_name='user_edit_global_perms', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_edit_global_perms_update", + route_name="user_edit_global_perms_update", + request_method="POST", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) + + config.add_route(name="user_update", pattern=r"/users/{user_id:\d+}/update", user_route=True) + config.add_view( + UsersView, + attr="user_update", + route_name="user_update", + request_method="POST", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) + + config.add_route(name="user_delete", pattern=r"/users/{user_id:\d+}/delete", user_route=True) + config.add_view( + UsersView, + attr="user_delete", + route_name="user_delete", + request_method="POST", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='user_edit_global_perms_update', - pattern=r'/users/{user_id:\d+}/edit/global_permissions/update', - user_route=True) + name="user_enable_force_password_reset", pattern=r"/users/{user_id:\d+}/password_reset_enable", user_route=True + ) config.add_view( UsersView, - attr='user_edit_global_perms_update', - route_name='user_edit_global_perms_update', request_method='POST', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_enable_force_password_reset", + route_name="user_enable_force_password_reset", + request_method="POST", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='user_update', - pattern=r'/users/{user_id:\d+}/update', - user_route=True) + name="user_disable_force_password_reset", + pattern=r"/users/{user_id:\d+}/password_reset_disable", + user_route=True, + ) config.add_view( UsersView, - attr='user_update', - route_name='user_update', request_method='POST', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_disable_force_password_reset", + route_name="user_disable_force_password_reset", + request_method="POST", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='user_delete', - pattern=r'/users/{user_id:\d+}/delete', - user_route=True) + name="user_create_personal_repo_group", pattern=r"/users/{user_id:\d+}/create_repo_group", user_route=True + ) config.add_view( UsersView, - attr='user_delete', - route_name='user_delete', request_method='POST', - renderer='rhodecode:templates/admin/users/user_edit.mako') - - config.add_route( - name='user_enable_force_password_reset', - pattern=r'/users/{user_id:\d+}/password_reset_enable', - user_route=True) - config.add_view( - UsersView, - attr='user_enable_force_password_reset', - route_name='user_enable_force_password_reset', request_method='POST', - renderer='rhodecode:templates/admin/users/user_edit.mako') - - config.add_route( - name='user_disable_force_password_reset', - pattern=r'/users/{user_id:\d+}/password_reset_disable', - user_route=True) - config.add_view( - UsersView, - attr='user_disable_force_password_reset', - route_name='user_disable_force_password_reset', request_method='POST', - renderer='rhodecode:templates/admin/users/user_edit.mako') - - config.add_route( - name='user_create_personal_repo_group', - pattern=r'/users/{user_id:\d+}/create_repo_group', - user_route=True) - config.add_view( - UsersView, - attr='user_create_personal_repo_group', - route_name='user_create_personal_repo_group', request_method='POST', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_create_personal_repo_group", + route_name="user_create_personal_repo_group", + request_method="POST", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) # user notice - config.add_route( - name='user_notice_dismiss', - pattern=r'/users/{user_id:\d+}/notice_dismiss', - user_route=True) + config.add_route(name="user_notice_dismiss", pattern=r"/users/{user_id:\d+}/notice_dismiss", user_route=True) config.add_view( UsersView, - attr='user_notice_dismiss', - route_name='user_notice_dismiss', request_method='POST', - renderer='json_ext', xhr=True) + attr="user_notice_dismiss", + route_name="user_notice_dismiss", + request_method="POST", + renderer="json_ext", + xhr=True, + ) # user auth tokens - config.add_route( - name='edit_user_auth_tokens', - pattern=r'/users/{user_id:\d+}/edit/auth_tokens', - user_route=True) + config.add_route(name="edit_user_auth_tokens", pattern=r"/users/{user_id:\d+}/edit/auth_tokens", user_route=True) config.add_view( UsersView, - attr='auth_tokens', - route_name='edit_user_auth_tokens', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="auth_tokens", + route_name="edit_user_auth_tokens", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='edit_user_auth_tokens_view', - pattern=r'/users/{user_id:\d+}/edit/auth_tokens/view', - user_route=True) + name="edit_user_auth_tokens_view", pattern=r"/users/{user_id:\d+}/edit/auth_tokens/view", user_route=True + ) config.add_view( UsersView, - attr='auth_tokens_view', - route_name='edit_user_auth_tokens_view', request_method='POST', - renderer='json_ext', xhr=True) + attr="auth_tokens_view", + route_name="edit_user_auth_tokens_view", + request_method="POST", + renderer="json_ext", + xhr=True, + ) config.add_route( - name='edit_user_auth_tokens_add', - pattern=r'/users/{user_id:\d+}/edit/auth_tokens/new', - user_route=True) - config.add_view( - UsersView, - attr='auth_tokens_add', - route_name='edit_user_auth_tokens_add', request_method='POST') + name="edit_user_auth_tokens_add", pattern=r"/users/{user_id:\d+}/edit/auth_tokens/new", user_route=True + ) + config.add_view(UsersView, attr="auth_tokens_add", route_name="edit_user_auth_tokens_add", request_method="POST") config.add_route( - name='edit_user_auth_tokens_delete', - pattern=r'/users/{user_id:\d+}/edit/auth_tokens/delete', - user_route=True) + name="edit_user_auth_tokens_delete", pattern=r"/users/{user_id:\d+}/edit/auth_tokens/delete", user_route=True + ) config.add_view( - UsersView, - attr='auth_tokens_delete', - route_name='edit_user_auth_tokens_delete', request_method='POST') + UsersView, attr="auth_tokens_delete", route_name="edit_user_auth_tokens_delete", request_method="POST" + ) # user ssh keys - config.add_route( - name='edit_user_ssh_keys', - pattern=r'/users/{user_id:\d+}/edit/ssh_keys', - user_route=True) + config.add_route(name="edit_user_ssh_keys", pattern=r"/users/{user_id:\d+}/edit/ssh_keys", user_route=True) config.add_view( UsersView, - attr='ssh_keys', - route_name='edit_user_ssh_keys', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="ssh_keys", + route_name="edit_user_ssh_keys", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='edit_user_ssh_keys_generate_keypair', - pattern=r'/users/{user_id:\d+}/edit/ssh_keys/generate', - user_route=True) + name="edit_user_ssh_keys_generate_keypair", + pattern=r"/users/{user_id:\d+}/edit/ssh_keys/generate", + user_route=True, + ) config.add_view( UsersView, - attr='ssh_keys_generate_keypair', - route_name='edit_user_ssh_keys_generate_keypair', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="ssh_keys_generate_keypair", + route_name="edit_user_ssh_keys_generate_keypair", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) + + config.add_route(name="edit_user_ssh_keys_add", pattern=r"/users/{user_id:\d+}/edit/ssh_keys/new", user_route=True) + config.add_view(UsersView, attr="ssh_keys_add", route_name="edit_user_ssh_keys_add", request_method="POST") config.add_route( - name='edit_user_ssh_keys_add', - pattern=r'/users/{user_id:\d+}/edit/ssh_keys/new', - user_route=True) - config.add_view( - UsersView, - attr='ssh_keys_add', - route_name='edit_user_ssh_keys_add', request_method='POST') - - config.add_route( - name='edit_user_ssh_keys_delete', - pattern=r'/users/{user_id:\d+}/edit/ssh_keys/delete', - user_route=True) - config.add_view( - UsersView, - attr='ssh_keys_delete', - route_name='edit_user_ssh_keys_delete', request_method='POST') + name="edit_user_ssh_keys_delete", pattern=r"/users/{user_id:\d+}/edit/ssh_keys/delete", user_route=True + ) + config.add_view(UsersView, attr="ssh_keys_delete", route_name="edit_user_ssh_keys_delete", request_method="POST") # user emails - config.add_route( - name='edit_user_emails', - pattern=r'/users/{user_id:\d+}/edit/emails', - user_route=True) + config.add_route(name="edit_user_emails", pattern=r"/users/{user_id:\d+}/edit/emails", user_route=True) config.add_view( UsersView, - attr='emails', - route_name='edit_user_emails', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="emails", + route_name="edit_user_emails", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) + + config.add_route(name="edit_user_emails_add", pattern=r"/users/{user_id:\d+}/edit/emails/new", user_route=True) + config.add_view(UsersView, attr="emails_add", route_name="edit_user_emails_add", request_method="POST") config.add_route( - name='edit_user_emails_add', - pattern=r'/users/{user_id:\d+}/edit/emails/new', - user_route=True) - config.add_view( - UsersView, - attr='emails_add', - route_name='edit_user_emails_add', request_method='POST') - - config.add_route( - name='edit_user_emails_delete', - pattern=r'/users/{user_id:\d+}/edit/emails/delete', - user_route=True) - config.add_view( - UsersView, - attr='emails_delete', - route_name='edit_user_emails_delete', request_method='POST') + name="edit_user_emails_delete", pattern=r"/users/{user_id:\d+}/edit/emails/delete", user_route=True + ) + config.add_view(UsersView, attr="emails_delete", route_name="edit_user_emails_delete", request_method="POST") # user IPs - config.add_route( - name='edit_user_ips', - pattern=r'/users/{user_id:\d+}/edit/ips', - user_route=True) + config.add_route(name="edit_user_ips", pattern=r"/users/{user_id:\d+}/edit/ips", user_route=True) config.add_view( UsersView, - attr='ips', - route_name='edit_user_ips', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="ips", + route_name="edit_user_ips", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='edit_user_ips_add', - pattern=r'/users/{user_id:\d+}/edit/ips/new', - user_route_with_default=True) # enabled for default user too - config.add_view( - UsersView, - attr='ips_add', - route_name='edit_user_ips_add', request_method='POST') + name="edit_user_ips_add", pattern=r"/users/{user_id:\d+}/edit/ips/new", user_route_with_default=True + ) # enabled for default user too + config.add_view(UsersView, attr="ips_add", route_name="edit_user_ips_add", request_method="POST") config.add_route( - name='edit_user_ips_delete', - pattern=r'/users/{user_id:\d+}/edit/ips/delete', - user_route_with_default=True) # enabled for default user too - config.add_view( - UsersView, - attr='ips_delete', - route_name='edit_user_ips_delete', request_method='POST') + name="edit_user_ips_delete", pattern=r"/users/{user_id:\d+}/edit/ips/delete", user_route_with_default=True + ) # enabled for default user too + config.add_view(UsersView, attr="ips_delete", route_name="edit_user_ips_delete", request_method="POST") # user perms config.add_route( - name='edit_user_perms_summary', - pattern=r'/users/{user_id:\d+}/edit/permissions_summary', - user_route=True) + name="edit_user_perms_summary", pattern=r"/users/{user_id:\d+}/edit/permissions_summary", user_route=True + ) config.add_view( UsersView, - attr='user_perms_summary', - route_name='edit_user_perms_summary', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_perms_summary", + route_name="edit_user_perms_summary", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='edit_user_perms_summary_json', - pattern=r'/users/{user_id:\d+}/edit/permissions_summary/json', - user_route=True) + name="edit_user_perms_summary_json", + pattern=r"/users/{user_id:\d+}/edit/permissions_summary/json", + user_route=True, + ) config.add_view( UsersView, - attr='user_perms_summary_json', - route_name='edit_user_perms_summary_json', request_method='GET', - renderer='json_ext') + attr="user_perms_summary_json", + route_name="edit_user_perms_summary_json", + request_method="GET", + renderer="json_ext", + ) # user user groups management config.add_route( - name='edit_user_groups_management', - pattern=r'/users/{user_id:\d+}/edit/groups_management', - user_route=True) + name="edit_user_groups_management", pattern=r"/users/{user_id:\d+}/edit/groups_management", user_route=True + ) config.add_view( UsersView, - attr='groups_management', - route_name='edit_user_groups_management', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="groups_management", + route_name="edit_user_groups_management", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='edit_user_groups_management_updates', - pattern=r'/users/{user_id:\d+}/edit/edit_user_groups_management/updates', - user_route=True) + name="edit_user_groups_management_updates", + pattern=r"/users/{user_id:\d+}/edit/edit_user_groups_management/updates", + user_route=True, + ) config.add_view( UsersView, - attr='groups_management_updates', - route_name='edit_user_groups_management_updates', request_method='POST') + attr="groups_management_updates", + route_name="edit_user_groups_management_updates", + request_method="POST", + ) # user audit logs - config.add_route( - name='edit_user_audit_logs', - pattern=r'/users/{user_id:\d+}/edit/audit', user_route=True) + config.add_route(name="edit_user_audit_logs", pattern=r"/users/{user_id:\d+}/edit/audit", user_route=True) config.add_view( UsersView, - attr='user_audit_logs', - route_name='edit_user_audit_logs', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_audit_logs", + route_name="edit_user_audit_logs", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='edit_user_audit_logs_download', - pattern=r'/users/{user_id:\d+}/edit/audit/download', user_route=True) + name="edit_user_audit_logs_download", pattern=r"/users/{user_id:\d+}/edit/audit/download", user_route=True + ) config.add_view( UsersView, - attr='user_audit_logs_download', - route_name='edit_user_audit_logs_download', request_method='GET', - renderer='string') + attr="user_audit_logs_download", + route_name="edit_user_audit_logs_download", + request_method="GET", + renderer="string", + ) # user caches - config.add_route( - name='edit_user_caches', - pattern=r'/users/{user_id:\d+}/edit/caches', - user_route=True) + config.add_route(name="edit_user_caches", pattern=r"/users/{user_id:\d+}/edit/caches", user_route=True) config.add_view( UsersView, - attr='user_caches', - route_name='edit_user_caches', request_method='GET', - renderer='rhodecode:templates/admin/users/user_edit.mako') + attr="user_caches", + route_name="edit_user_caches", + request_method="GET", + renderer="rhodecode:templates/admin/users/user_edit.mako", + ) config.add_route( - name='edit_user_caches_update', - pattern=r'/users/{user_id:\d+}/edit/caches/update', - user_route=True) - config.add_view( - UsersView, - attr='user_caches_update', - route_name='edit_user_caches_update', request_method='POST') + name="edit_user_caches_update", pattern=r"/users/{user_id:\d+}/edit/caches/update", user_route=True + ) + config.add_view(UsersView, attr="user_caches_update", route_name="edit_user_caches_update", request_method="POST") # user-groups admin - config.add_route( - name='user_groups', - pattern='/user_groups') + config.add_route(name="user_groups", pattern="/user_groups") config.add_view( AdminUserGroupsView, - attr='user_groups_list', - route_name='user_groups', request_method='GET', - renderer='rhodecode:templates/admin/user_groups/user_groups.mako') + attr="user_groups_list", + route_name="user_groups", + request_method="GET", + renderer="rhodecode:templates/admin/user_groups/user_groups.mako", + ) - config.add_route( - name='user_groups_data', - pattern='/user_groups_data') + config.add_route(name="user_groups_data", pattern="/user_groups_data") config.add_view( AdminUserGroupsView, - attr='user_groups_list_data', - route_name='user_groups_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="user_groups_list_data", + route_name="user_groups_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='user_groups_new', - pattern='/user_groups/new') + config.add_route(name="user_groups_new", pattern="/user_groups/new") config.add_view( AdminUserGroupsView, - attr='user_groups_new', - route_name='user_groups_new', request_method='GET', - renderer='rhodecode:templates/admin/user_groups/user_group_add.mako') + attr="user_groups_new", + route_name="user_groups_new", + request_method="GET", + renderer="rhodecode:templates/admin/user_groups/user_group_add.mako", + ) - config.add_route( - name='user_groups_create', - pattern='/user_groups/create') + config.add_route(name="user_groups_create", pattern="/user_groups/create") config.add_view( AdminUserGroupsView, - attr='user_groups_create', - route_name='user_groups_create', request_method='POST', - renderer='rhodecode:templates/admin/user_groups/user_group_add.mako') + attr="user_groups_create", + route_name="user_groups_create", + request_method="POST", + renderer="rhodecode:templates/admin/user_groups/user_group_add.mako", + ) # repos admin - config.add_route( - name='repos', - pattern='/repos') + config.add_route(name="repos", pattern="/repos") config.add_view( AdminReposView, - attr='repository_list', - route_name='repos', request_method='GET', - renderer='rhodecode:templates/admin/repos/repos.mako') + attr="repository_list", + route_name="repos", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repos.mako", + ) - config.add_route( - name='repos_data', - pattern='/repos_data') + config.add_route(name="repos_data", pattern="/repos_data") config.add_view( AdminReposView, - attr='repository_list_data', - route_name='repos_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="repository_list_data", + route_name="repos_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='repo_new', - pattern='/repos/new') + config.add_route(name="repo_new", pattern="/repos/new") config.add_view( AdminReposView, - attr='repository_new', - route_name='repo_new', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_add.mako') + attr="repository_new", + route_name="repo_new", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_add.mako", + ) - config.add_route( - name='repo_create', - pattern='/repos/create') + config.add_route(name="repo_create", pattern="/repos/create") config.add_view( AdminReposView, - attr='repository_create', - route_name='repo_create', request_method='POST', - renderer='rhodecode:templates/admin/repos/repos.mako') + attr="repository_create", + route_name="repo_create", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repos.mako", + ) # repo groups admin - config.add_route( - name='repo_groups', - pattern='/repo_groups') + config.add_route(name="repo_groups", pattern="/repo_groups") config.add_view( AdminRepoGroupsView, - attr='repo_group_list', - route_name='repo_groups', request_method='GET', - renderer='rhodecode:templates/admin/repo_groups/repo_groups.mako') + attr="repo_group_list", + route_name="repo_groups", + request_method="GET", + renderer="rhodecode:templates/admin/repo_groups/repo_groups.mako", + ) - config.add_route( - name='repo_groups_data', - pattern='/repo_groups_data') + config.add_route(name="repo_groups_data", pattern="/repo_groups_data") config.add_view( AdminRepoGroupsView, - attr='repo_group_list_data', - route_name='repo_groups_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="repo_group_list_data", + route_name="repo_groups_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='repo_group_new', - pattern='/repo_group/new') + config.add_route(name="repo_group_new", pattern="/repo_group/new") config.add_view( AdminRepoGroupsView, - attr='repo_group_new', - route_name='repo_group_new', request_method='GET', - renderer='rhodecode:templates/admin/repo_groups/repo_group_add.mako') + attr="repo_group_new", + route_name="repo_group_new", + request_method="GET", + renderer="rhodecode:templates/admin/repo_groups/repo_group_add.mako", + ) - config.add_route( - name='repo_group_create', - pattern='/repo_group/create') + config.add_route(name="repo_group_create", pattern="/repo_group/create") config.add_view( AdminRepoGroupsView, - attr='repo_group_create', - route_name='repo_group_create', request_method='POST', - renderer='rhodecode:templates/admin/repo_groups/repo_group_add.mako') + attr="repo_group_create", + route_name="repo_group_create", + request_method="POST", + renderer="rhodecode:templates/admin/repo_groups/repo_group_add.mako", + ) def includeme(config): @@ -1097,37 +1082,29 @@ def includeme(config): nav_includeme(config) # main admin routes - config.add_route( - name='admin_home', pattern=ADMIN_PREFIX) + config.add_route(name="admin_home", pattern=ADMIN_PREFIX) config.add_view( AdminMainView, - attr='admin_main', - route_name='admin_home', request_method='GET', - renderer='rhodecode:templates/admin/main.mako') + attr="admin_main", + route_name="admin_home", + request_method="GET", + renderer="rhodecode:templates/admin/main.mako", + ) # pr global redirect config.add_route( - name='pull_requests_global_0', # backward compat - pattern=ADMIN_PREFIX + r'/pull_requests/{pull_request_id:\d+}') - config.add_view( - AdminMainView, - attr='pull_requests', - route_name='pull_requests_global_0', request_method='GET') + name="pull_requests_global_0", # backward compat + pattern=ADMIN_PREFIX + r"/pull_requests/{pull_request_id:\d+}", + ) + config.add_view(AdminMainView, attr="pull_requests", route_name="pull_requests_global_0", request_method="GET") config.add_route( - name='pull_requests_global_1', # backward compat - pattern=ADMIN_PREFIX + r'/pull-requests/{pull_request_id:\d+}') - config.add_view( - AdminMainView, - attr='pull_requests', - route_name='pull_requests_global_1', request_method='GET') + name="pull_requests_global_1", # backward compat + pattern=ADMIN_PREFIX + r"/pull-requests/{pull_request_id:\d+}", + ) + config.add_view(AdminMainView, attr="pull_requests", route_name="pull_requests_global_1", request_method="GET") - config.add_route( - name='pull_requests_global', - pattern=ADMIN_PREFIX + r'/pull-request/{pull_request_id:\d+}') - config.add_view( - AdminMainView, - attr='pull_requests', - route_name='pull_requests_global', request_method='GET') + config.add_route(name="pull_requests_global", pattern=ADMIN_PREFIX + r"/pull-request/{pull_request_id:\d+}") + config.add_view(AdminMainView, attr="pull_requests", route_name="pull_requests_global", request_method="GET") config.include(admin_routes, route_prefix=ADMIN_PREFIX) diff --git a/rhodecode/apps/admin/tests/test_admin_audit_logs.py b/rhodecode/apps/admin/tests/test_admin_audit_logs.py index 2160466b..54d59089 100644 --- a/rhodecode/apps/admin/tests/test_admin_audit_logs.py +++ b/rhodecode/apps/admin/tests/test_admin_audit_logs.py @@ -30,34 +30,33 @@ from rhodecode.model.db import UserLog from rhodecode.model.meta import Session -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestAdminController(object): - - @pytest.fixture(scope='class', autouse=True) + @pytest.fixture(scope="class", autouse=True) def prepare(self, request, baseapp): UserLog.query().delete() Session().commit() def strptime(val): - fmt = '%Y-%m-%d %H:%M:%S' - if '.' not in val: + fmt = "%Y-%m-%d %H:%M:%S" + if "." not in val: return datetime.datetime.strptime(val, fmt) nofrag, frag = val.split(".") date = datetime.datetime.strptime(nofrag, fmt) frag = frag[:6] # truncate to microseconds - frag += (6 - len(frag)) * '0' # add 0s + frag += (6 - len(frag)) * "0" # add 0s return date.replace(microsecond=int(frag)) - with open(os.path.join(FIXTURES, 'journal_dump.csv')) as f: + with open(os.path.join(FIXTURES, "journal_dump.csv")) as f: for row in csv.DictReader(f): ul = UserLog() for k, v in row.items(): v = safe_str(v) - if k == 'action_date': + if k == "action_date": v = strptime(v) - if k in ['user_id', 'repository_id']: + if k in ["user_id", "repository_id"]: # nullable due to FK problems v = None setattr(ul, k, v) @@ -70,86 +69,75 @@ class TestAdminController(object): Session().commit() def test_index(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs')) - response.mustcontain('Admin audit logs') + response = self.app.get(route_path("admin_audit_logs")) + response.mustcontain("Admin audit logs") def test_filter_all_entries(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs')) + response = self.app.get(route_path("admin_audit_logs")) all_count = UserLog.query().count() - response.mustcontain('%s entries' % all_count) + response.mustcontain("%s entries" % all_count) def test_filter_journal_filter_exact_match_on_repository(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='repository:rhodecode'))) - response.mustcontain('3 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="repository:rhodecode"))) + response.mustcontain("3 entries") def test_filter_journal_filter_exact_match_on_repository_CamelCase(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='repository:RhodeCode'))) - response.mustcontain('3 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="repository:RhodeCode"))) + response.mustcontain("3 entries") def test_filter_journal_filter_wildcard_on_repository(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='repository:*test*'))) - response.mustcontain('862 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="repository:*test*"))) + response.mustcontain("862 entries") def test_filter_journal_filter_prefix_on_repository(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='repository:test*'))) - response.mustcontain('257 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="repository:test*"))) + response.mustcontain("257 entries") def test_filter_journal_filter_prefix_on_repository_CamelCase(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='repository:Test*'))) - response.mustcontain('257 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="repository:Test*"))) + response.mustcontain("257 entries") def test_filter_journal_filter_prefix_on_repository_and_user(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='repository:test* AND username:demo'))) - response.mustcontain('130 entries') + response = self.app.get( + route_path("admin_audit_logs", params=dict(filter="repository:test* AND username:demo")) + ) + response.mustcontain("130 entries") def test_filter_journal_filter_prefix_on_repository_or_target_repo(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='repository:test* OR repository:rhodecode'))) - response.mustcontain('260 entries') # 257 + 3 + response = self.app.get( + route_path("admin_audit_logs", params=dict(filter="repository:test* OR repository:rhodecode")) + ) + response.mustcontain("260 entries") # 257 + 3 def test_filter_journal_filter_exact_match_on_username(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='username:demo'))) - response.mustcontain('1087 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="username:demo"))) + response.mustcontain("1087 entries") def test_filter_journal_filter_exact_match_on_username_camelCase(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='username:DemO'))) - response.mustcontain('1087 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="username:DemO"))) + response.mustcontain("1087 entries") def test_filter_journal_filter_wildcard_on_username(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='username:*test*'))) - entries_count = UserLog.query().filter(UserLog.username.ilike('%test%')).count() - response.mustcontain('{} entries'.format(entries_count)) + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="username:*test*"))) + entries_count = UserLog.query().filter(UserLog.username.ilike("%test%")).count() + response.mustcontain("{} entries".format(entries_count)) def test_filter_journal_filter_prefix_on_username(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='username:demo*'))) - response.mustcontain('1101 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="username:demo*"))) + response.mustcontain("1101 entries") def test_filter_journal_filter_prefix_on_user_or_other_user(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='username:demo OR username:volcan'))) - response.mustcontain('1095 entries') # 1087 + 8 + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="username:demo OR username:volcan"))) + response.mustcontain("1095 entries") # 1087 + 8 def test_filter_journal_filter_wildcard_on_action(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='action:*pull_request*'))) - response.mustcontain('187 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="action:*pull_request*"))) + response.mustcontain("187 entries") def test_filter_journal_filter_on_date(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='date:20121010'))) - response.mustcontain('47 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="date:20121010"))) + response.mustcontain("47 entries") def test_filter_journal_filter_on_date_2(self, autologin_user): - response = self.app.get(route_path('admin_audit_logs', - params=dict(filter='date:20121020'))) - response.mustcontain('17 entries') + response = self.app.get(route_path("admin_audit_logs", params=dict(filter="date:20121020"))) + response.mustcontain("17 entries") diff --git a/rhodecode/apps/admin/tests/test_admin_auth_settings.py b/rhodecode/apps/admin/tests/test_admin_auth_settings.py index 49d97828..65dc5691 100644 --- a/rhodecode/apps/admin/tests/test_admin_auth_settings.py +++ b/rhodecode/apps/admin/tests/test_admin_auth_settings.py @@ -25,41 +25,35 @@ from rhodecode.model.settings import SettingsModel def assert_auth_settings_updated(response): - assert response.status_int == 302, 'Expected response HTTP Found 302' - assert_session_flash(response, 'Auth settings updated successfully') + assert response.status_int == 302, "Expected response HTTP Found 302" + assert_session_flash(response, "Auth settings updated successfully") @pytest.mark.usefixtures("autologin_user", "app") class TestAuthSettingsView(object): - - def _enable_plugins(self, plugins_list, csrf_token, override=None, - verify_response=False): - test_url = '/_admin/auth' + def _enable_plugins(self, plugins_list, csrf_token, override=None, verify_response=False): + test_url = "/_admin/auth" params = { - 'auth_plugins': plugins_list, - 'csrf_token': csrf_token, + "auth_plugins": plugins_list, + "csrf_token": csrf_token, } if override: params.update(override) _enabled_plugins = [] - for plugin in plugins_list.split(','): - plugin_name = plugin.partition('#')[-1] - enabled_plugin = '%s_enabled' % plugin_name - cache_ttl = '%s_cache_ttl' % plugin_name + for plugin in plugins_list.split(","): + plugin_name = plugin.partition("#")[-1] + enabled_plugin = "%s_enabled" % plugin_name + cache_ttl = "%s_cache_ttl" % plugin_name # default params that are needed for each plugin, # `enabled` and `cache_ttl` - params.update({ - enabled_plugin: True, - cache_ttl: 0 - }) + params.update({enabled_plugin: True, cache_ttl: 0}) _enabled_plugins.append(enabled_plugin) # we need to clean any enabled plugin before, since they require # form params to be present - db_plugin = SettingsModel().get_setting_by_name('auth_plugins') - db_plugin.app_settings_value = \ - 'egg:rhodecode-enterprise-ce#rhodecode' + db_plugin = SettingsModel().get_setting_by_name("auth_plugins") + db_plugin.app_settings_value = "egg:rhodecode-enterprise-ce#rhodecode" Session().add(db_plugin) Session().commit() for _plugin in _enabled_plugins: @@ -75,49 +69,52 @@ class TestAuthSettingsView(object): return params def _post_ldap_settings(self, params, override=None, force=False): - - params.update({ - 'filter': 'user', - 'user_member_of': '', - 'user_search_base': '', - 'user_search_filter': 'test_filter', - - 'host': 'dc.example.com', - 'port': '999', - 'timeout': 3600, - 'tls_kind': 'PLAIN', - 'tls_reqcert': 'NEVER', - 'tls_cert_dir':'/etc/openldap/cacerts', - 'dn_user': 'test_user', - 'dn_pass': 'test_pass', - 'base_dn': 'test_base_dn', - 'search_scope': 'BASE', - 'attr_login': 'test_attr_login', - 'attr_firstname': 'ima', - 'attr_lastname': 'tester', - 'attr_email': 'test@example.com', - 'cache_ttl': '0', - }) + params.update( + { + "filter": "user", + "user_member_of": "", + "user_search_base": "", + "user_search_filter": "test_filter", + "host": "dc.example.com", + "port": "999", + "timeout": 3600, + "tls_kind": "PLAIN", + "tls_reqcert": "NEVER", + "tls_cert_dir": "/etc/openldap/cacerts", + "dn_user": "test_user", + "dn_pass": "test_pass", + "base_dn": "test_base_dn", + "search_scope": "BASE", + "attr_login": "test_attr_login", + "attr_firstname": "ima", + "attr_lastname": "tester", + "attr_email": "test@example.com", + "cache_ttl": "0", + } + ) if force: params = {} params.update(override or {}) - test_url = '/_admin/auth/ldap/' + test_url = "/_admin/auth/ldap/" response = self.app.post(url=test_url, params=params) return response def test_index(self): - response = self.app.get('/_admin/auth') - response.mustcontain('Authentication Plugins') + response = self.app.get("/_admin/auth") + response.mustcontain("Authentication Plugins") - @pytest.mark.parametrize("disable_plugin, needs_import", [ - ('egg:rhodecode-enterprise-ce#headers', None), - ('egg:rhodecode-enterprise-ce#crowd', None), - ('egg:rhodecode-enterprise-ce#jasig_cas', None), - ('egg:rhodecode-enterprise-ce#ldap', None), - ('egg:rhodecode-enterprise-ce#pam', "pam"), - ]) + @pytest.mark.parametrize( + "disable_plugin, needs_import", + [ + ("egg:rhodecode-enterprise-ce#headers", None), + ("egg:rhodecode-enterprise-ce#crowd", None), + ("egg:rhodecode-enterprise-ce#jasig_cas", None), + ("egg:rhodecode-enterprise-ce#ldap", None), + ("egg:rhodecode-enterprise-ce#pam", "pam"), + ], + ) def test_disable_plugin(self, csrf_token, disable_plugin, needs_import): # TODO: johbo: "pam" is currently not available on darwin, # although the docs state that it should work on darwin. @@ -125,76 +122,76 @@ class TestAuthSettingsView(object): pytest.importorskip(needs_import) self._enable_plugins( - 'egg:rhodecode-enterprise-ce#rhodecode,' + disable_plugin, - csrf_token, verify_response=True) + "egg:rhodecode-enterprise-ce#rhodecode," + disable_plugin, csrf_token, verify_response=True + ) - self._enable_plugins( - 'egg:rhodecode-enterprise-ce#rhodecode', csrf_token, - verify_response=True) + self._enable_plugins("egg:rhodecode-enterprise-ce#rhodecode", csrf_token, verify_response=True) def test_ldap_save_settings(self, csrf_token): params = self._enable_plugins( - 'egg:rhodecode-enterprise-ce#rhodecode,' - 'egg:rhodecode-enterprise-ce#ldap', - csrf_token) + "egg:rhodecode-enterprise-ce#rhodecode,egg:rhodecode-enterprise-ce#ldap", csrf_token + ) response = self._post_ldap_settings(params) assert_auth_settings_updated(response) new_settings = SettingsModel().get_auth_settings() - assert new_settings['auth_ldap_host'] == u'dc.example.com', \ - 'fail db write compare' + assert new_settings["auth_ldap_host"] == "dc.example.com", "fail db write compare" def test_ldap_error_form_wrong_port_number(self, csrf_token): params = self._enable_plugins( - 'egg:rhodecode-enterprise-ce#rhodecode,' - 'egg:rhodecode-enterprise-ce#ldap', - csrf_token) - invalid_port_value = 'invalid-port-number' - response = self._post_ldap_settings(params, override={ - 'port': invalid_port_value, - }) + "egg:rhodecode-enterprise-ce#rhodecode,egg:rhodecode-enterprise-ce#ldap", csrf_token + ) + invalid_port_value = "invalid-port-number" + response = self._post_ldap_settings( + params, + override={ + "port": invalid_port_value, + }, + ) assertr = response.assert_response() - assertr.element_contains( - '.form .field #port ~ .error-message', - invalid_port_value) + assertr.element_contains(".form .field #port ~ .error-message", invalid_port_value) def test_ldap_error_form(self, csrf_token): params = self._enable_plugins( - 'egg:rhodecode-enterprise-ce#rhodecode,' - 'egg:rhodecode-enterprise-ce#ldap', - csrf_token) - response = self._post_ldap_settings(params, override={ - 'attr_login': '', - }) - response.mustcontain("""The LDAP Login""" - """ attribute of the CN must be specified""") + "egg:rhodecode-enterprise-ce#rhodecode,egg:rhodecode-enterprise-ce#ldap", csrf_token + ) + response = self._post_ldap_settings( + params, + override={ + "attr_login": "", + }, + ) + response.mustcontain( + """The LDAP Login""" + """ attribute of the CN must be specified""" + ) def test_post_ldap_group_settings(self, csrf_token): params = self._enable_plugins( - 'egg:rhodecode-enterprise-ce#rhodecode,' - 'egg:rhodecode-enterprise-ce#ldap', - csrf_token) + "egg:rhodecode-enterprise-ce#rhodecode,egg:rhodecode-enterprise-ce#ldap", csrf_token + ) - response = self._post_ldap_settings(params, override={ - 'host': 'dc-legacy.example.com', - 'port': '999', - 'tls_kind': 'PLAIN', - 'tls_reqcert': 'NEVER', - 'dn_user': 'test_user', - 'dn_pass': 'test_pass', - 'base_dn': 'test_base_dn', - 'filter': 'test_filter', - 'search_scope': 'BASE', - 'attr_login': 'test_attr_login', - 'attr_firstname': 'ima', - 'attr_lastname': 'tester', - 'attr_email': 'test@example.com', - 'cache_ttl': '60', - 'csrf_token': csrf_token, - } + response = self._post_ldap_settings( + params, + override={ + "host": "dc-legacy.example.com", + "port": "999", + "tls_kind": "PLAIN", + "tls_reqcert": "NEVER", + "dn_user": "test_user", + "dn_pass": "test_pass", + "base_dn": "test_base_dn", + "filter": "test_filter", + "search_scope": "BASE", + "attr_login": "test_attr_login", + "attr_firstname": "ima", + "attr_lastname": "tester", + "attr_email": "test@example.com", + "cache_ttl": "60", + "csrf_token": csrf_token, + }, ) assert_auth_settings_updated(response) new_settings = SettingsModel().get_auth_settings() - assert new_settings['auth_ldap_host'] == u'dc-legacy.example.com', \ - 'fail db write compare' + assert new_settings["auth_ldap_host"] == "dc-legacy.example.com", "fail db write compare" diff --git a/rhodecode/apps/admin/tests/test_admin_defaults.py b/rhodecode/apps/admin/tests/test_admin_defaults.py index a51ba6c9..4b23360e 100644 --- a/rhodecode/apps/admin/tests/test_admin_defaults.py +++ b/rhodecode/apps/admin/tests/test_admin_defaults.py @@ -25,44 +25,41 @@ from rhodecode.model.settings import SettingsModel @pytest.mark.usefixtures("app") class TestDefaultsView(object): - def test_index(self, autologin_user): - response = self.app.get(route_path('admin_defaults_repositories')) - response.mustcontain('default_repo_private') - response.mustcontain('default_repo_enable_statistics') - response.mustcontain('default_repo_enable_downloads') - response.mustcontain('default_repo_enable_locking') + response = self.app.get(route_path("admin_defaults_repositories")) + response.mustcontain("default_repo_private") + response.mustcontain("default_repo_enable_statistics") + response.mustcontain("default_repo_enable_downloads") + response.mustcontain("default_repo_enable_locking") def test_update_params_true_hg(self, autologin_user, csrf_token): params = { - 'default_repo_enable_locking': True, - 'default_repo_enable_downloads': True, - 'default_repo_enable_statistics': True, - 'default_repo_private': True, - 'default_repo_type': 'hg', - 'csrf_token': csrf_token, + "default_repo_enable_locking": True, + "default_repo_enable_downloads": True, + "default_repo_enable_statistics": True, + "default_repo_private": True, + "default_repo_type": "hg", + "csrf_token": csrf_token, } - response = self.app.post( - route_path('admin_defaults_repositories_update'), params=params) - assert_session_flash(response, 'Default settings updated successfully') + response = self.app.post(route_path("admin_defaults_repositories_update"), params=params) + assert_session_flash(response, "Default settings updated successfully") defs = SettingsModel().get_default_repo_settings() - del params['csrf_token'] + del params["csrf_token"] assert params == defs def test_update_params_false_git(self, autologin_user, csrf_token): params = { - 'default_repo_enable_locking': False, - 'default_repo_enable_downloads': False, - 'default_repo_enable_statistics': False, - 'default_repo_private': False, - 'default_repo_type': 'git', - 'csrf_token': csrf_token, + "default_repo_enable_locking": False, + "default_repo_enable_downloads": False, + "default_repo_enable_statistics": False, + "default_repo_private": False, + "default_repo_type": "git", + "csrf_token": csrf_token, } - response = self.app.post( - route_path('admin_defaults_repositories_update'), params=params) - assert_session_flash(response, 'Default settings updated successfully') + response = self.app.post(route_path("admin_defaults_repositories_update"), params=params) + assert_session_flash(response, "Default settings updated successfully") defs = SettingsModel().get_default_repo_settings() - del params['csrf_token'] + del params["csrf_token"] assert params == defs diff --git a/rhodecode/apps/admin/tests/test_admin_main_views.py b/rhodecode/apps/admin/tests/test_admin_main_views.py index aa48394c..7f56b970 100644 --- a/rhodecode/apps/admin/tests/test_admin_main_views.py +++ b/rhodecode/apps/admin/tests/test_admin_main_views.py @@ -26,41 +26,39 @@ fixture = Fixture() class TestAdminMainView(TestController): - def test_access_admin_home(self): self.log_user() - response = self.app.get(route_path('admin_home'), status=200) + response = self.app.get(route_path("admin_home"), status=200) response.mustcontain("Administration area") - @pytest.mark.parametrize('view', [ - 'pull_requests_global', - ]) + @pytest.mark.parametrize( + "view", + [ + "pull_requests_global", + ], + ) def test_redirect_pull_request_view_global(self, view): self.log_user() - self.app.get( - route_path(view, pull_request_id='xxxx'), - status=404) + self.app.get(route_path(view, pull_request_id="xxxx"), status=404) @pytest.mark.backends("git", "hg") - @pytest.mark.parametrize('view', [ - 'pull_requests_global', - 'pull_requests_global_0', - 'pull_requests_global_1', - ]) + @pytest.mark.parametrize( + "view", + [ + "pull_requests_global", + "pull_requests_global_0", + "pull_requests_global_1", + ], + ) def test_redirect_pull_request_view(self, view, pr_util): self.log_user() pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id repo_name = pull_request.target_repo.repo_name - response = self.app.get( - route_path(view, pull_request_id=pull_request_id), - status=302) - assert response.location.endswith( - 'pull-request/{}'.format(pull_request_id)) + response = self.app.get(route_path(view, pull_request_id=pull_request_id), status=302) + assert response.location.endswith("pull-request/{}".format(pull_request_id)) - redirect_url = route_path( - 'pullrequest_show', repo_name=repo_name, - pull_request_id=pull_request_id) + redirect_url = route_path("pullrequest_show", repo_name=repo_name, pull_request_id=pull_request_id) assert redirect_url in response.location diff --git a/rhodecode/apps/admin/tests/test_admin_permissions.py b/rhodecode/apps/admin/tests/test_admin_permissions.py index 6545ba71..46cb1ad5 100644 --- a/rhodecode/apps/admin/tests/test_admin_permissions.py +++ b/rhodecode/apps/admin/tests/test_admin_permissions.py @@ -22,231 +22,275 @@ from rhodecode.model.db import User, UserIpMap from rhodecode.model.meta import Session from rhodecode.model.permission import PermissionModel from rhodecode.model.ssh_key import SshKeyModel -from rhodecode.tests import ( - TestController, clear_cache_regions, assert_session_flash) +from rhodecode.tests import TestController, clear_cache_regions, assert_session_flash from rhodecode.tests.routes import route_path class TestAdminPermissionsController(TestController): - - @pytest.fixture(scope='class', autouse=True) + @pytest.fixture(scope="class", autouse=True) def prepare(self, request): # cleanup and reset to default permissions after @request.addfinalizer def cleanup(): - PermissionModel().create_default_user_permissions( - User.get_default_user(), force=True) + PermissionModel().create_default_user_permissions(User.get_default_user(), force=True) def test_index_application(self): self.log_user() - self.app.get(route_path('admin_permissions_application')) + self.app.get(route_path("admin_permissions_application")) @pytest.mark.parametrize( - 'anonymous, default_register, default_register_message, default_password_reset,' - 'default_extern_activate, expect_error, expect_form_error', [ - (True, 'hg.register.none', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual', - False, False), - (True, 'hg.register.manual_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.auto', - False, False), - (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual', - False, False), - (True, 'hg.register.auto_activate', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual', - False, False), - (True, 'hg.register.XXX', '', 'hg.password_reset.enabled', 'hg.extern_activate.manual', - False, True), - (True, '', '', 'hg.password_reset.enabled', '', True, False), - ]) + "anonymous, default_register, default_register_message, default_password_reset," + "default_extern_activate, expect_error, expect_form_error", + [ + (True, "hg.register.none", "", "hg.password_reset.enabled", "hg.extern_activate.manual", False, False), + ( + True, + "hg.register.manual_activate", + "", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + False, + False, + ), + ( + True, + "hg.register.auto_activate", + "", + "hg.password_reset.enabled", + "hg.extern_activate.manual", + False, + False, + ), + ( + True, + "hg.register.auto_activate", + "", + "hg.password_reset.enabled", + "hg.extern_activate.manual", + False, + False, + ), + (True, "hg.register.XXX", "", "hg.password_reset.enabled", "hg.extern_activate.manual", False, True), + (True, "", "", "hg.password_reset.enabled", "", True, False), + ], + ) def test_update_application_permissions( - self, anonymous, default_register, default_register_message, default_password_reset, - default_extern_activate, expect_error, expect_form_error): - + self, + anonymous, + default_register, + default_register_message, + default_password_reset, + default_extern_activate, + expect_error, + expect_form_error, + ): self.log_user() # TODO: anonymous access set here to False, breaks some other tests params = { - 'csrf_token': self.csrf_token, - 'anonymous': anonymous, - 'default_register': default_register, - 'default_register_message': default_register_message, - 'default_password_reset': default_password_reset, - 'default_extern_activate': default_extern_activate, + "csrf_token": self.csrf_token, + "anonymous": anonymous, + "default_register": default_register, + "default_register_message": default_register_message, + "default_password_reset": default_password_reset, + "default_extern_activate": default_extern_activate, } - response = self.app.post(route_path('admin_permissions_application_update'), - params=params) + response = self.app.post(route_path("admin_permissions_application_update"), params=params) if expect_form_error: assert response.status_int == 200 - response.mustcontain('Value must be one of') + response.mustcontain("Value must be one of") else: if expect_error: - msg = 'Error occurred during update of permissions' + msg = "Error occurred during update of permissions" else: - msg = 'Application permissions updated successfully' + msg = "Application permissions updated successfully" assert_session_flash(response, msg) def test_index_object(self): self.log_user() - self.app.get(route_path('admin_permissions_object')) + self.app.get(route_path("admin_permissions_object")) @pytest.mark.parametrize( - 'repo, repo_group, user_group, expect_error, expect_form_error', [ - ('repository.none', 'group.none', 'usergroup.none', False, False), - ('repository.read', 'group.read', 'usergroup.read', False, False), - ('repository.write', 'group.write', 'usergroup.write', - False, False), - ('repository.admin', 'group.admin', 'usergroup.admin', - False, False), - ('repository.XXX', 'group.admin', 'usergroup.admin', False, True), - ('', '', '', True, False), - ]) - def test_update_object_permissions(self, repo, repo_group, user_group, - expect_error, expect_form_error): + "repo, repo_group, user_group, expect_error, expect_form_error", + [ + ("repository.none", "group.none", "usergroup.none", False, False), + ("repository.read", "group.read", "usergroup.read", False, False), + ("repository.write", "group.write", "usergroup.write", False, False), + ("repository.admin", "group.admin", "usergroup.admin", False, False), + ("repository.XXX", "group.admin", "usergroup.admin", False, True), + ("", "", "", True, False), + ], + ) + def test_update_object_permissions(self, repo, repo_group, user_group, expect_error, expect_form_error): self.log_user() params = { - 'csrf_token': self.csrf_token, - 'default_repo_perm': repo, - 'overwrite_default_repo': False, - 'default_group_perm': repo_group, - 'overwrite_default_group': False, - 'default_user_group_perm': user_group, - 'overwrite_default_user_group': False, + "csrf_token": self.csrf_token, + "default_repo_perm": repo, + "overwrite_default_repo": False, + "default_group_perm": repo_group, + "overwrite_default_group": False, + "default_user_group_perm": user_group, + "overwrite_default_user_group": False, } - response = self.app.post(route_path('admin_permissions_object_update'), - params=params) + response = self.app.post(route_path("admin_permissions_object_update"), params=params) if expect_form_error: assert response.status_int == 200 - response.mustcontain('Value must be one of') + response.mustcontain("Value must be one of") else: if expect_error: - msg = 'Error occurred during update of permissions' + msg = "Error occurred during update of permissions" else: - msg = 'Object permissions updated successfully' + msg = "Object permissions updated successfully" assert_session_flash(response, msg) def test_index_global(self): self.log_user() - self.app.get(route_path('admin_permissions_global')) + self.app.get(route_path("admin_permissions_global")) @pytest.mark.parametrize( - 'repo_create, repo_create_write, user_group_create, repo_group_create,' - 'fork_create, inherit_default_permissions, expect_error,' - 'expect_form_error', [ - ('hg.create.none', 'hg.create.write_on_repogroup.false', - 'hg.usergroup.create.false', 'hg.repogroup.create.false', - 'hg.fork.none', 'hg.inherit_default_perms.false', False, False), - ('hg.create.repository', 'hg.create.write_on_repogroup.true', - 'hg.usergroup.create.true', 'hg.repogroup.create.true', - 'hg.fork.repository', 'hg.inherit_default_perms.false', - False, False), - ('hg.create.XXX', 'hg.create.write_on_repogroup.true', - 'hg.usergroup.create.true', 'hg.repogroup.create.true', - 'hg.fork.repository', 'hg.inherit_default_perms.false', - False, True), - ('', '', '', '', '', '', True, False), - ]) + "repo_create, repo_create_write, user_group_create, repo_group_create," + "fork_create, inherit_default_permissions, expect_error," + "expect_form_error", + [ + ( + "hg.create.none", + "hg.create.write_on_repogroup.false", + "hg.usergroup.create.false", + "hg.repogroup.create.false", + "hg.fork.none", + "hg.inherit_default_perms.false", + False, + False, + ), + ( + "hg.create.repository", + "hg.create.write_on_repogroup.true", + "hg.usergroup.create.true", + "hg.repogroup.create.true", + "hg.fork.repository", + "hg.inherit_default_perms.false", + False, + False, + ), + ( + "hg.create.XXX", + "hg.create.write_on_repogroup.true", + "hg.usergroup.create.true", + "hg.repogroup.create.true", + "hg.fork.repository", + "hg.inherit_default_perms.false", + False, + True, + ), + ("", "", "", "", "", "", True, False), + ], + ) def test_update_global_permissions( - self, repo_create, repo_create_write, user_group_create, - repo_group_create, fork_create, inherit_default_permissions, - expect_error, expect_form_error): + self, + repo_create, + repo_create_write, + user_group_create, + repo_group_create, + fork_create, + inherit_default_permissions, + expect_error, + expect_form_error, + ): self.log_user() params = { - 'csrf_token': self.csrf_token, - 'default_repo_create': repo_create, - 'default_repo_create_on_write': repo_create_write, - 'default_user_group_create': user_group_create, - 'default_repo_group_create': repo_group_create, - 'default_fork_create': fork_create, - 'default_inherit_default_permissions': inherit_default_permissions + "csrf_token": self.csrf_token, + "default_repo_create": repo_create, + "default_repo_create_on_write": repo_create_write, + "default_user_group_create": user_group_create, + "default_repo_group_create": repo_group_create, + "default_fork_create": fork_create, + "default_inherit_default_permissions": inherit_default_permissions, } - response = self.app.post(route_path('admin_permissions_global_update'), - params=params) + response = self.app.post(route_path("admin_permissions_global_update"), params=params) if expect_form_error: assert response.status_int == 200 - response.mustcontain('Value must be one of') + response.mustcontain("Value must be one of") else: if expect_error: - msg = 'Error occurred during update of permissions' + msg = "Error occurred during update of permissions" else: - msg = 'Global permissions updated successfully' + msg = "Global permissions updated successfully" assert_session_flash(response, msg) def test_index_ips(self): self.log_user() - response = self.app.get(route_path('admin_permissions_ips')) - response.mustcontain('All IP addresses are allowed') + response = self.app.get(route_path("admin_permissions_ips")) + response.mustcontain("All IP addresses are allowed") def test_add_delete_ips(self): - clear_cache_regions(['sql_cache_short']) + clear_cache_regions(["sql_cache_short"]) self.log_user() # ADD default_user_id = User.get_default_user_id() self.app.post( - route_path('edit_user_ips_add', user_id=default_user_id), - params={'new_ip': '0.0.0.0/24', 'csrf_token': self.csrf_token}) + route_path("edit_user_ips_add", user_id=default_user_id), + params={"new_ip": "0.0.0.0/24", "csrf_token": self.csrf_token}, + ) - response = self.app.get(route_path('admin_permissions_ips')) - response.mustcontain('0.0.0.0/24') - response.mustcontain('0.0.0.0 - 0.0.0.255') + response = self.app.get(route_path("admin_permissions_ips")) + response.mustcontain("0.0.0.0/24") + response.mustcontain("0.0.0.0 - 0.0.0.255") # DELETE default_user_id = User.get_default_user_id() - del_ip_id = UserIpMap.query().filter(UserIpMap.user_id == - default_user_id).first().ip_id + del_ip_id = UserIpMap.query().filter(UserIpMap.user_id == default_user_id).first().ip_id response = self.app.post( - route_path('edit_user_ips_delete', user_id=default_user_id), - params={'del_ip_id': del_ip_id, 'csrf_token': self.csrf_token}) + route_path("edit_user_ips_delete", user_id=default_user_id), + params={"del_ip_id": del_ip_id, "csrf_token": self.csrf_token}, + ) - assert_session_flash(response, 'Removed ip address from user whitelist') + assert_session_flash(response, "Removed ip address from user whitelist") - clear_cache_regions(['sql_cache_short']) - response = self.app.get(route_path('admin_permissions_ips')) - response.mustcontain('All IP addresses are allowed') - response.mustcontain(no=['0.0.0.0/24']) - response.mustcontain(no=['0.0.0.0 - 0.0.0.255']) + clear_cache_regions(["sql_cache_short"]) + response = self.app.get(route_path("admin_permissions_ips")) + response.mustcontain("All IP addresses are allowed") + response.mustcontain(no=["0.0.0.0/24"]) + response.mustcontain(no=["0.0.0.0 - 0.0.0.255"]) def test_index_overview(self): self.log_user() - self.app.get(route_path('admin_permissions_overview')) + self.app.get(route_path("admin_permissions_overview")) def test_ssh_keys(self): self.log_user() - self.app.get(route_path('admin_permissions_ssh_keys'), status=200) + self.app.get(route_path("admin_permissions_ssh_keys"), status=200) def test_ssh_keys_data(self, user_util, xhr_header): self.log_user() - response = self.app.get(route_path('admin_permissions_ssh_keys_data'), - extra_environ=xhr_header) - assert response.json == {u'data': [], u'draw': None, - u'recordsFiltered': 0, u'recordsTotal': 0} + response = self.app.get(route_path("admin_permissions_ssh_keys_data"), extra_environ=xhr_header) + assert response.json == {"data": [], "draw": None, "recordsFiltered": 0, "recordsTotal": 0} dummy_user = user_util.create_user() - SshKeyModel().create(dummy_user, 'ab:cd:ef', 'KEYKEY', 'test_key') + SshKeyModel().create(dummy_user, "ab:cd:ef", "KEYKEY", "test_key") Session().commit() - response = self.app.get(route_path('admin_permissions_ssh_keys_data'), - extra_environ=xhr_header) - assert response.json['data'][0]['fingerprint'] == 'ab:cd:ef' + response = self.app.get(route_path("admin_permissions_ssh_keys_data"), extra_environ=xhr_header) + assert response.json["data"][0]["fingerprint"] == "ab:cd:ef" def test_ssh_keys_update(self): self.log_user() response = self.app.post( - route_path('admin_permissions_ssh_keys_update'), - dict(csrf_token=self.csrf_token), status=302) + route_path("admin_permissions_ssh_keys_update"), dict(csrf_token=self.csrf_token), status=302 + ) - assert_session_flash( - response, 'Updated SSH keys file') + assert_session_flash(response, "Updated SSH keys file") def test_ssh_keys_update_disabled(self): self.log_user() from rhodecode.apps.admin.views.permissions import AdminPermissionsView - with mock.patch.object(AdminPermissionsView, 'ssh_enabled', - return_value=False): - response = self.app.post( - route_path('admin_permissions_ssh_keys_update'), - dict(csrf_token=self.csrf_token), status=302) - assert_session_flash( - response, 'SSH key support is disabled in .ini file') \ No newline at end of file + with mock.patch.object(AdminPermissionsView, "ssh_enabled", return_value=False): + response = self.app.post( + route_path("admin_permissions_ssh_keys_update"), dict(csrf_token=self.csrf_token), status=302 + ) + + assert_session_flash(response, "SSH key support is disabled in .ini file") diff --git a/rhodecode/apps/admin/tests/test_admin_repos.py b/rhodecode/apps/admin/tests/test_admin_repos.py index 18a4927f..6b51a2e8 100644 --- a/rhodecode/apps/admin/tests/test_admin_repos.py +++ b/rhodecode/apps/admin/tests/test_admin_repos.py @@ -27,15 +27,18 @@ from rhodecode.apps._base import ADMIN_PREFIX from rhodecode.lib import auth from rhodecode.lib.utils2 import safe_str from rhodecode.lib import helpers as h -from rhodecode.model.db import ( - Repository, RepoGroup, UserRepoToPerm, User, Permission) +from rhodecode.model.db import Repository, RepoGroup, UserRepoToPerm, User, Permission from rhodecode.model.meta import Session from rhodecode.model.repo import RepoModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.user import UserModel from rhodecode.tests import ( - login_user_session, assert_session_flash, TEST_USER_ADMIN_LOGIN, - TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + login_user_session, + assert_session_flash, + TEST_USER_ADMIN_LOGIN, + TEST_USER_REGULAR_LOGIN, + TEST_USER_REGULAR_PASS, +) from rhodecode.tests.fixtures.rc_fixture import Fixture, error_function from rhodecode.tests.utils import repo_on_filesystem from rhodecode.tests.routes import route_path @@ -44,146 +47,140 @@ fixture = Fixture() def _get_permission_for_user(user, repo): - perm = UserRepoToPerm.query()\ - .filter(UserRepoToPerm.repository == - Repository.get_by_repo_name(repo))\ - .filter(UserRepoToPerm.user == User.get_by_username(user))\ + perm = ( + UserRepoToPerm.query() + .filter(UserRepoToPerm.repository == Repository.get_by_repo_name(repo)) + .filter(UserRepoToPerm.user == User.get_by_username(user)) .all() + ) return perm @pytest.mark.usefixtures("app") class TestAdminRepos(object): - def test_repo_list(self, autologin_user, user_util, xhr_header): repo = user_util.create_repo() repo_name = repo.repo_name - response = self.app.get( - route_path('repos_data'), status=200, - extra_environ=xhr_header) + response = self.app.get(route_path("repos_data"), status=200, extra_environ=xhr_header) response.mustcontain(repo_name) def test_create_page_restricted_to_single_backend(self, autologin_user, backend): - with mock.patch('rhodecode.BACKENDS', {'git': 'git'}): - response = self.app.get(route_path('repo_new'), status=200) + with mock.patch("rhodecode.BACKENDS", {"git": "git"}): + response = self.app.get(route_path("repo_new"), status=200) assert_response = response.assert_response() - element = assert_response.get_element('[name=repo_type]') - assert element.get('value') == 'git' + element = assert_response.get_element("[name=repo_type]") + assert element.get("value") == "git" def test_create_page_non_restricted_backends(self, autologin_user, backend): - response = self.app.get(route_path('repo_new'), status=200) + response = self.app.get(route_path("repo_new"), status=200) assert_response = response.assert_response() - assert ['hg', 'git', 'svn'] == [x.get('value') for x in assert_response.get_elements('[name=repo_type]')] + assert ["hg", "git", "svn"] == [x.get("value") for x in assert_response.get_elements("[name=repo_type]")] - @pytest.mark.parametrize( - "suffix", ['', 'xxa'], ids=['', 'non-ascii']) + @pytest.mark.parametrize("suffix", ["", "xxa"], ids=["", "non-ascii"]) def test_create(self, autologin_user, backend, suffix, csrf_token): repo_name_unicode = backend.new_repo_name(suffix=suffix) repo_name = repo_name_unicode - description_unicode = 'description for newly created repo' + suffix + description_unicode = "description for newly created repo" + suffix description = description_unicode response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, - csrf_token=csrf_token), - status=302) + csrf_token=csrf_token, + ), + status=302, + ) - self.assert_repository_is_created_correctly( - repo_name, description, backend) + self.assert_repository_is_created_correctly(repo_name, description, backend) def test_create_numeric_name(self, autologin_user, backend, csrf_token): - numeric_repo = '1234' + numeric_repo = "1234" repo_name = numeric_repo - description = 'description for newly created repo' + numeric_repo + description = "description for newly created repo" + numeric_repo self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) try: self.assert_repository_is_created_correctly(repo_name, description, backend) finally: RepoModel().delete(numeric_repo) Session().commit() - @pytest.mark.parametrize("suffix", ['', '_ąćę'], ids=['', 'non-ascii']) - def test_create_in_group( - self, autologin_user, backend, suffix, csrf_token): + @pytest.mark.parametrize("suffix", ["", "_ąćę"], ids=["", "non-ascii"]) + def test_create_in_group(self, autologin_user, backend, suffix, csrf_token): # create GROUP - group_name = f'sometest_{backend.alias}' - gr = RepoGroupModel().create(group_name=group_name, - group_description='test', - owner=TEST_USER_ADMIN_LOGIN) + group_name = f"sometest_{backend.alias}" + gr = RepoGroupModel().create(group_name=group_name, group_description="test", owner=TEST_USER_ADMIN_LOGIN) Session().commit() - repo_name = f'ingroup{suffix}' + repo_name = f"ingroup{suffix}" repo_name_full = RepoGroup.url_sep().join([group_name, repo_name]) - description = 'description for newly created repo' + description = "description for newly created repo" self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=safe_str(repo_name), repo_type=backend.alias, repo_description=description, repo_group=gr.group_id, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) # TODO: johbo: Cleanup work to fixture try: - self.assert_repository_is_created_correctly( - repo_name_full, description, backend) + self.assert_repository_is_created_correctly(repo_name_full, description, backend) new_repo = RepoModel().get_by_repo_name(repo_name_full) - inherited_perms = UserRepoToPerm.query().filter( - UserRepoToPerm.repository_id == new_repo.repo_id).all() + inherited_perms = UserRepoToPerm.query().filter(UserRepoToPerm.repository_id == new_repo.repo_id).all() assert len(inherited_perms) == 1 finally: RepoModel().delete(repo_name_full) RepoGroupModel().delete(group_name) Session().commit() - def test_create_in_group_numeric_name( - self, autologin_user, backend, csrf_token): + def test_create_in_group_numeric_name(self, autologin_user, backend, csrf_token): # create GROUP - group_name = 'sometest_%s' % backend.alias - gr = RepoGroupModel().create(group_name=group_name, - group_description='test', - owner=TEST_USER_ADMIN_LOGIN) + group_name = "sometest_%s" % backend.alias + gr = RepoGroupModel().create(group_name=group_name, group_description="test", owner=TEST_USER_ADMIN_LOGIN) Session().commit() - repo_name = '12345' + repo_name = "12345" repo_name_full = RepoGroup.url_sep().join([group_name, repo_name]) - description = 'description for newly created repo' + description = "description for newly created repo" self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, repo_group=gr.group_id, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) # TODO: johbo: Cleanup work to fixture try: - self.assert_repository_is_created_correctly( - repo_name_full, description, backend) + self.assert_repository_is_created_correctly(repo_name_full, description, backend) new_repo = RepoModel().get_by_repo_name(repo_name_full) - inherited_perms = UserRepoToPerm.query()\ - .filter(UserRepoToPerm.repository_id == new_repo.repo_id).all() + inherited_perms = UserRepoToPerm.query().filter(UserRepoToPerm.repository_id == new_repo.repo_id).all() assert len(inherited_perms) == 1 finally: RepoModel().delete(repo_name_full) @@ -191,77 +188,74 @@ class TestAdminRepos(object): Session().commit() def test_create_in_group_without_needed_permissions(self, backend): - session = login_user_session( - self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + session = login_user_session(self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) csrf_token = auth.get_csrf_token(session) # revoke user_model = UserModel() # disable fork and create on default user - user_model.revoke_perm(User.DEFAULT_USER, 'hg.create.repository') - user_model.grant_perm(User.DEFAULT_USER, 'hg.create.none') - user_model.revoke_perm(User.DEFAULT_USER, 'hg.fork.repository') - user_model.grant_perm(User.DEFAULT_USER, 'hg.fork.none') + user_model.revoke_perm(User.DEFAULT_USER, "hg.create.repository") + user_model.grant_perm(User.DEFAULT_USER, "hg.create.none") + user_model.revoke_perm(User.DEFAULT_USER, "hg.fork.repository") + user_model.grant_perm(User.DEFAULT_USER, "hg.fork.none") # disable on regular user - user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.repository') - user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.none') - user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.repository') - user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.none') + user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, "hg.create.repository") + user_model.grant_perm(TEST_USER_REGULAR_LOGIN, "hg.create.none") + user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, "hg.fork.repository") + user_model.grant_perm(TEST_USER_REGULAR_LOGIN, "hg.fork.none") Session().commit() # create GROUP - group_name = 'reg_sometest_%s' % backend.alias - gr = RepoGroupModel().create(group_name=group_name, - group_description='test', - owner=TEST_USER_ADMIN_LOGIN) + group_name = "reg_sometest_%s" % backend.alias + gr = RepoGroupModel().create(group_name=group_name, group_description="test", owner=TEST_USER_ADMIN_LOGIN) Session().commit() repo_group_id = gr.group_id - group_name_allowed = 'reg_sometest_allowed_%s' % backend.alias + group_name_allowed = "reg_sometest_allowed_%s" % backend.alias gr_allowed = RepoGroupModel().create( - group_name=group_name_allowed, - group_description='test', - owner=TEST_USER_REGULAR_LOGIN) + group_name=group_name_allowed, group_description="test", owner=TEST_USER_REGULAR_LOGIN + ) allowed_repo_group_id = gr_allowed.group_id Session().commit() - repo_name = 'ingroup' - description = 'description for newly created repo' + repo_name = "ingroup" + description = "description for newly created repo" response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, repo_group=repo_group_id, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) - response.mustcontain('Invalid value') + response.mustcontain("Invalid value") # user is allowed to create in this group - repo_name = 'ingroup' - repo_name_full = RepoGroup.url_sep().join( - [group_name_allowed, repo_name]) - description = 'description for newly created repo' + repo_name = "ingroup" + repo_name_full = RepoGroup.url_sep().join([group_name_allowed, repo_name]) + description = "description for newly created repo" response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, repo_group=allowed_repo_group_id, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) # TODO: johbo: Cleanup in pytest fixture try: - self.assert_repository_is_created_correctly( - repo_name_full, description, backend) + self.assert_repository_is_created_correctly(repo_name_full, description, backend) new_repo = RepoModel().get_by_repo_name(repo_name_full) - inherited_perms = UserRepoToPerm.query().filter( - UserRepoToPerm.repository_id == new_repo.repo_id).all() + inherited_perms = UserRepoToPerm.query().filter(UserRepoToPerm.repository_id == new_repo.repo_id).all() assert len(inherited_perms) == 1 assert repo_on_filesystem(repo_name_full) @@ -271,25 +265,21 @@ class TestAdminRepos(object): RepoGroupModel().delete(group_name_allowed) Session().commit() - def test_create_in_group_inherit_permissions(self, autologin_user, backend, - csrf_token): + def test_create_in_group_inherit_permissions(self, autologin_user, backend, csrf_token): # create GROUP - group_name = 'sometest_%s' % backend.alias - gr = RepoGroupModel().create(group_name=group_name, - group_description='test', - owner=TEST_USER_ADMIN_LOGIN) - perm = Permission.get_by_key('repository.write') - RepoGroupModel().grant_user_permission( - gr, TEST_USER_REGULAR_LOGIN, perm) + group_name = "sometest_%s" % backend.alias + gr = RepoGroupModel().create(group_name=group_name, group_description="test", owner=TEST_USER_ADMIN_LOGIN) + perm = Permission.get_by_key("repository.write") + RepoGroupModel().grant_user_permission(gr, TEST_USER_REGULAR_LOGIN, perm) # add repo permissions Session().commit() repo_group_id = gr.group_id - repo_name = 'ingroup_inherited_%s' % backend.alias + repo_name = "ingroup_inherited_%s" % backend.alias repo_name_full = RepoGroup.url_sep().join([group_name, repo_name]) - description = 'description for newly created repo' + description = "description for newly created repo" self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, @@ -297,12 +287,13 @@ class TestAdminRepos(object): repo_description=description, repo_group=repo_group_id, repo_copy_permissions=True, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) # TODO: johbo: Cleanup to pytest fixture try: - self.assert_repository_is_created_correctly( - repo_name_full, description, backend) + self.assert_repository_is_created_correctly(repo_name_full, description, backend) except Exception: RepoGroupModel().delete(group_name) Session().commit() @@ -310,41 +301,38 @@ class TestAdminRepos(object): # check if inherited permissions are applied new_repo = RepoModel().get_by_repo_name(repo_name_full) - inherited_perms = UserRepoToPerm.query().filter( - UserRepoToPerm.repository_id == new_repo.repo_id).all() + inherited_perms = UserRepoToPerm.query().filter(UserRepoToPerm.repository_id == new_repo.repo_id).all() assert len(inherited_perms) == 2 - assert TEST_USER_REGULAR_LOGIN in [ - x.user.username for x in inherited_perms] - assert 'repository.write' in [ - x.permission.permission_name for x in inherited_perms] + assert TEST_USER_REGULAR_LOGIN in [x.user.username for x in inherited_perms] + assert "repository.write" in [x.permission.permission_name for x in inherited_perms] RepoModel().delete(repo_name_full) RepoGroupModel().delete(group_name) Session().commit() - @pytest.mark.xfail_backends( - "git", "hg", reason="Missing reposerver support") - def test_create_with_clone_uri(self, autologin_user, backend, reposerver, - csrf_token): + @pytest.mark.xfail_backends("git", "hg", reason="Missing reposerver support") + def test_create_with_clone_uri(self, autologin_user, backend, reposerver, csrf_token): source_repo = backend.create_repo(number_of_commits=2) source_repo_name = source_repo.repo_name reposerver.serve(source_repo.scm_instance()) repo_name = backend.new_repo_name() response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, - repo_description='', + repo_description="", clone_uri=reposerver.url, - csrf_token=csrf_token), - status=302) + csrf_token=csrf_token, + ), + status=302, + ) # Should be redirected to the creating page - response.mustcontain('repo_creating') + response.mustcontain("repo_creating") # Expecting that both repositories have same history source_repo = RepoModel().get_by_repo_name(source_repo_name) @@ -356,117 +344,115 @@ class TestAdminRepos(object): assert source_vcs.commit_ids == repo_vcs.commit_ids @pytest.mark.xfail_backends("svn", reason="Depends on import support") - def test_create_remote_repo_wrong_clone_uri(self, autologin_user, backend, - csrf_token): + def test_create_remote_repo_wrong_clone_uri(self, autologin_user, backend, csrf_token): repo_name = backend.new_repo_name() - description = 'description for newly created repo' + description = "description for newly created repo" response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, - clone_uri='http://repo.invalid/repo', - csrf_token=csrf_token)) - response.mustcontain('invalid clone url') + clone_uri="http://repo.invalid/repo", + csrf_token=csrf_token, + ), + ) + response.mustcontain("invalid clone url") @pytest.mark.xfail_backends("svn", reason="Depends on import support") - def test_create_remote_repo_wrong_clone_uri_hg_svn( - self, autologin_user, backend, csrf_token): + def test_create_remote_repo_wrong_clone_uri_hg_svn(self, autologin_user, backend, csrf_token): repo_name = backend.new_repo_name() - description = 'description for newly created repo' + description = "description for newly created repo" response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, - clone_uri='svn+http://svn.invalid/repo', - csrf_token=csrf_token)) - response.mustcontain('invalid clone url') + clone_uri="svn+http://svn.invalid/repo", + csrf_token=csrf_token, + ), + ) + response.mustcontain("invalid clone url") - def test_create_with_git_suffix( - self, autologin_user, backend, csrf_token): + def test_create_with_git_suffix(self, autologin_user, backend, csrf_token): repo_name = backend.new_repo_name() + ".git" - description = 'description for newly created repo' + description = "description for newly created repo" response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, - csrf_token=csrf_token)) - response.mustcontain('Repository name cannot end with .git') - - def test_default_user_cannot_access_private_repo_in_a_group( - self, autologin_user, user_util, backend): + csrf_token=csrf_token, + ), + ) + response.mustcontain("Repository name cannot end with .git") + def test_default_user_cannot_access_private_repo_in_a_group(self, autologin_user, user_util, backend): group = user_util.create_repo_group() - repo = backend.create_repo( - repo_private=True, repo_group=group, repo_copy_permissions=True) + repo = backend.create_repo(repo_private=True, repo_group=group, repo_copy_permissions=True) - permissions = _get_permission_for_user( - user='default', repo=repo.repo_name) + permissions = _get_permission_for_user(user="default", repo=repo.repo_name) assert len(permissions) == 1 - assert permissions[0].permission.permission_name == 'repository.none' + assert permissions[0].permission.permission_name == "repository.none" assert permissions[0].repository.private is True def test_create_on_top_level_without_permissions(self, backend): - session = login_user_session( - self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + session = login_user_session(self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) csrf_token = auth.get_csrf_token(session) # revoke user_model = UserModel() # disable fork and create on default user - user_model.revoke_perm(User.DEFAULT_USER, 'hg.create.repository') - user_model.grant_perm(User.DEFAULT_USER, 'hg.create.none') - user_model.revoke_perm(User.DEFAULT_USER, 'hg.fork.repository') - user_model.grant_perm(User.DEFAULT_USER, 'hg.fork.none') + user_model.revoke_perm(User.DEFAULT_USER, "hg.create.repository") + user_model.grant_perm(User.DEFAULT_USER, "hg.create.none") + user_model.revoke_perm(User.DEFAULT_USER, "hg.fork.repository") + user_model.grant_perm(User.DEFAULT_USER, "hg.fork.none") # disable on regular user - user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.repository') - user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.create.none') - user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.repository') - user_model.grant_perm(TEST_USER_REGULAR_LOGIN, 'hg.fork.none') + user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, "hg.create.repository") + user_model.grant_perm(TEST_USER_REGULAR_LOGIN, "hg.create.none") + user_model.revoke_perm(TEST_USER_REGULAR_LOGIN, "hg.fork.repository") + user_model.grant_perm(TEST_USER_REGULAR_LOGIN, "hg.fork.none") Session().commit() repo_name = backend.new_repo_name() - description = 'description for newly created repo' + description = "description for newly created repo" response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) - response.mustcontain( - "You do not have the permission to store repositories in " - "the root location.") + response.mustcontain("You do not have the permission to store repositories in the root location.") - @mock.patch.object(RepoModel, '_create_filesystem_repo', error_function) - def test_create_repo_when_filesystem_op_fails( - self, autologin_user, backend, csrf_token): + @mock.patch.object(RepoModel, "_create_filesystem_repo", error_function) + def test_create_repo_when_filesystem_op_fails(self, autologin_user, backend, csrf_token): repo_name = backend.new_repo_name() - description = 'description for newly created repo' + description = "description for newly created repo" response = self.app.post( - route_path('repo_create'), + route_path("repo_create"), fixture._get_repo_create_params( repo_private=False, repo_name=repo_name, repo_type=backend.alias, repo_description=description, - csrf_token=csrf_token)) + csrf_token=csrf_token, + ), + ) - assert_session_flash( - response, 'Error creating repository %s' % repo_name) + assert_session_flash(response, "Error creating repository %s" % repo_name) # repo must not be in db assert backend.repo is None # repo must not be in filesystem ! @@ -476,9 +462,8 @@ class TestAdminRepos(object): url_quoted_repo_name = urllib.parse.quote(repo_name) # run the check page that triggers the flash message - response = self.app.get( - route_path('repo_creating_check', repo_name=repo_name)) - assert response.json == {'result': True} + response = self.app.get(route_path("repo_creating_check", repo_name=repo_name)) + assert response.json == {"result": True} flash_msg = 'Created repository {}'.format(url_quoted_repo_name, repo_name) assert_session_flash(response, flash_msg) @@ -490,8 +475,7 @@ class TestAdminRepos(object): assert new_repo.description == description # test if the repository is visible in the list ? - response = self.app.get( - h.route_path('repo_summary', repo_name=repo_name)) + response = self.app.get(h.route_path("repo_summary", repo_name=repo_name)) response.mustcontain(repo_name) response.mustcontain(backend.alias) diff --git a/rhodecode/apps/admin/tests/test_admin_repository_groups.py b/rhodecode/apps/admin/tests/test_admin_repository_groups.py index 2dd22ccf..147e96f2 100644 --- a/rhodecode/apps/admin/tests/test_admin_repository_groups.py +++ b/rhodecode/apps/admin/tests/test_admin_repository_groups.py @@ -24,8 +24,7 @@ from rhodecode.lib import helpers as h from rhodecode.model.db import Repository, UserRepoToPerm, User, RepoGroup from rhodecode.model.meta import Session from rhodecode.model.repo_group import RepoGroupModel -from rhodecode.tests import ( - assert_session_flash, TEST_USER_REGULAR_LOGIN, TESTS_TMP_PATH) +from rhodecode.tests import assert_session_flash, TEST_USER_REGULAR_LOGIN, TESTS_TMP_PATH from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -34,85 +33,82 @@ fixture = Fixture() def _get_permission_for_user(user, repo): - perm = UserRepoToPerm.query()\ - .filter(UserRepoToPerm.repository == - Repository.get_by_repo_name(repo))\ - .filter(UserRepoToPerm.user == User.get_by_username(user))\ + perm = ( + UserRepoToPerm.query() + .filter(UserRepoToPerm.repository == Repository.get_by_repo_name(repo)) + .filter(UserRepoToPerm.user == User.get_by_username(user)) .all() + ) return perm @pytest.mark.usefixtures("app") class TestAdminRepositoryGroups(object): - def test_show_repo_groups(self, autologin_user): - self.app.get(route_path('repo_groups')) + self.app.get(route_path("repo_groups")) def test_show_repo_groups_data(self, autologin_user, xhr_header): - response = self.app.get(route_path( - 'repo_groups_data'), extra_environ=xhr_header) + response = self.app.get(route_path("repo_groups_data"), extra_environ=xhr_header) all_repo_groups = RepoGroup.query().count() - assert response.json['recordsTotal'] == all_repo_groups + assert response.json["recordsTotal"] == all_repo_groups def test_show_repo_groups_data_filtered(self, autologin_user, xhr_header): - response = self.app.get(route_path( - 'repo_groups_data', params={'search[value]': 'empty_search'}), - extra_environ=xhr_header) + response = self.app.get( + route_path("repo_groups_data", params={"search[value]": "empty_search"}), extra_environ=xhr_header + ) all_repo_groups = RepoGroup.query().count() - assert response.json['recordsTotal'] == all_repo_groups - assert response.json['recordsFiltered'] == 0 + assert response.json["recordsTotal"] == all_repo_groups + assert response.json["recordsFiltered"] == 0 def test_show_repo_groups_after_creating_group(self, autologin_user, xhr_header): - fixture.create_repo_group('test_repo_group') - response = self.app.get(route_path( - 'repo_groups_data'), extra_environ=xhr_header) - response.mustcontain('Edit'.format('test_repo_group')) - fixture.destroy_repo_group('test_repo_group') + fixture.create_repo_group("test_repo_group") + response = self.app.get(route_path("repo_groups_data"), extra_environ=xhr_header) + response.mustcontain('Edit'.format("test_repo_group")) + fixture.destroy_repo_group("test_repo_group") def test_new(self, autologin_user): - self.app.get(route_path('repo_group_new')) + self.app.get(route_path("repo_group_new")) def test_new_with_parent_group(self, autologin_user, user_util): gr = user_util.create_repo_group() - self.app.get(route_path('repo_group_new'), - params=dict(parent_group=gr.group_name)) + self.app.get(route_path("repo_group_new"), params=dict(parent_group=gr.group_name)) def test_new_by_regular_user_no_permission(self, autologin_regular_user): - self.app.get(route_path('repo_group_new'), status=403) + self.app.get(route_path("repo_group_new"), status=403) - @pytest.mark.parametrize('repo_group_name', [ - 'git_repo', - 'git_repo_ąć', - 'hg_repo', - '12345', - 'hg_repo_ąć', - ]) + @pytest.mark.parametrize( + "repo_group_name", + [ + "git_repo", + "git_repo_ąć", + "hg_repo", + "12345", + "hg_repo_ąć", + ], + ) def test_create(self, autologin_user, repo_group_name, csrf_token): repo_group_name_non_ascii = repo_group_name - description = 'description for newly created repo group' + description = "description for newly created repo group" response = self.app.post( - route_path('repo_group_create'), + route_path("repo_group_create"), fixture._get_group_create_params( - group_name=repo_group_name, - group_description=description, - csrf_token=csrf_token)) + group_name=repo_group_name, group_description=description, csrf_token=csrf_token + ), + ) # run the check page that triggers the flash message - repo_gr_url = h.route_path( - 'repo_group_home', repo_group_name=repo_group_name) + repo_gr_url = h.route_path("repo_group_home", repo_group_name=repo_group_name) assert_session_flash( - response, - 'Created repository group %s' % ( - repo_gr_url, repo_group_name_non_ascii)) + response, 'Created repository group %s' % (repo_gr_url, repo_group_name_non_ascii) + ) # # test if the repo group was created in the database - new_repo_group = RepoGroupModel()._get_repo_group( - repo_group_name_non_ascii) + new_repo_group = RepoGroupModel()._get_repo_group(repo_group_name_non_ascii) assert new_repo_group is not None assert new_repo_group.group_name == repo_group_name_non_ascii @@ -123,56 +119,58 @@ class TestAdminRepositoryGroups(object): response.mustcontain(repo_group_name) # test if the repository group was created on filesystem - is_on_filesystem = os.path.isdir( - os.path.join(TESTS_TMP_PATH, repo_group_name)) + is_on_filesystem = os.path.isdir(os.path.join(TESTS_TMP_PATH, repo_group_name)) if not is_on_filesystem: - self.fail('no repo group %s in filesystem' % repo_group_name) + self.fail("no repo group %s in filesystem" % repo_group_name) RepoGroupModel().delete(repo_group_name_non_ascii) Session().commit() - @pytest.mark.parametrize('repo_group_name', [ - 'git_repo', - 'git_repo_ąć', - 'hg_repo', - '12345', - 'hg_repo_ąć', - ]) + @pytest.mark.parametrize( + "repo_group_name", + [ + "git_repo", + "git_repo_ąć", + "hg_repo", + "12345", + "hg_repo_ąć", + ], + ) def test_create_subgroup(self, autologin_user, user_util, repo_group_name, csrf_token): parent_group = user_util.create_repo_group() parent_group_name = parent_group.group_name - expected_group_name = '{}/{}'.format( - parent_group_name, repo_group_name) + expected_group_name = "{}/{}".format(parent_group_name, repo_group_name) expected_group_name_non_ascii = expected_group_name try: response = self.app.post( - route_path('repo_group_create'), + route_path("repo_group_create"), fixture._get_group_create_params( group_name=repo_group_name, group_parent_id=parent_group.group_id, - group_description='Test desciption', - csrf_token=csrf_token)) + group_description="Test desciption", + csrf_token=csrf_token, + ), + ) assert_session_flash( response, - u'Created repository group %s' % ( - h.route_path('repo_group_home', - repo_group_name=expected_group_name), - expected_group_name_non_ascii)) + 'Created repository group %s' + % (h.route_path("repo_group_home", repo_group_name=expected_group_name), expected_group_name_non_ascii), + ) finally: RepoGroupModel().delete(expected_group_name_non_ascii) Session().commit() - def test_user_with_creation_permissions_cannot_create_subgroups( - self, autologin_regular_user, user_util): - - user_util.grant_user_permission( - TEST_USER_REGULAR_LOGIN, 'hg.repogroup.create.true') + def test_user_with_creation_permissions_cannot_create_subgroups(self, autologin_regular_user, user_util): + user_util.grant_user_permission(TEST_USER_REGULAR_LOGIN, "hg.repogroup.create.true") parent_group = user_util.create_repo_group() parent_group_id = parent_group.group_id self.app.get( - route_path('repo_group_new', - params=dict(parent_group=parent_group_id), ), - status=403) + route_path( + "repo_group_new", + params=dict(parent_group=parent_group_id), + ), + status=403, + ) diff --git a/rhodecode/apps/admin/tests/test_admin_settings.py b/rhodecode/apps/admin/tests/test_admin_settings.py index 982f5453..35cc3654 100644 --- a/rhodecode/apps/admin/tests/test_admin_settings.py +++ b/rhodecode/apps/admin/tests/test_admin_settings.py @@ -29,295 +29,288 @@ from rhodecode.tests import assert_session_flash from rhodecode.tests.routes import route_path -UPDATE_DATA_QUALNAME = 'rhodecode.model.update.UpdateModel.get_update_data' +UPDATE_DATA_QUALNAME = "rhodecode.model.update.UpdateModel.get_update_data" -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAdminSettingsController(object): - - @pytest.mark.parametrize('urlname', [ - 'admin_settings_vcs', - 'admin_settings_mapping', - 'admin_settings_global', - 'admin_settings_visual', - 'admin_settings_email', - 'admin_settings_hooks', - 'admin_settings_search', - ]) + @pytest.mark.parametrize( + "urlname", + [ + "admin_settings_vcs", + "admin_settings_mapping", + "admin_settings_global", + "admin_settings_visual", + "admin_settings_email", + "admin_settings_hooks", + "admin_settings_search", + ], + ) def test_simple_get(self, urlname): self.app.get(route_path(urlname)) def test_create_custom_hook(self, csrf_token): response = self.app.post( - route_path('admin_settings_hooks_update'), - params={ - 'new_hook_ui_key': 'test_hooks_1', - 'new_hook_ui_value': 'cd /tmp', - 'csrf_token': csrf_token}) + route_path("admin_settings_hooks_update"), + params={"new_hook_ui_key": "test_hooks_1", "new_hook_ui_value": "cd /tmp", "csrf_token": csrf_token}, + ) response = response.follow() - response.mustcontain('test_hooks_1') - response.mustcontain('cd /tmp') + response.mustcontain("test_hooks_1") + response.mustcontain("cd /tmp") def test_create_custom_hook_delete(self, csrf_token): response = self.app.post( - route_path('admin_settings_hooks_update'), - params={ - 'new_hook_ui_key': 'test_hooks_2', - 'new_hook_ui_value': 'cd /tmp2', - 'csrf_token': csrf_token}) + route_path("admin_settings_hooks_update"), + params={"new_hook_ui_key": "test_hooks_2", "new_hook_ui_value": "cd /tmp2", "csrf_token": csrf_token}, + ) response = response.follow() - response.mustcontain('test_hooks_2') - response.mustcontain('cd /tmp2') + response.mustcontain("test_hooks_2") + response.mustcontain("cd /tmp2") - hook_id = SettingsModel().get_ui_by_key('test_hooks_2').ui_id + hook_id = SettingsModel().get_ui_by_key("test_hooks_2").ui_id # delete - self.app.post( - route_path('admin_settings_hooks_delete'), - params={'hook_id': hook_id, 'csrf_token': csrf_token}) - response = self.app.get(route_path('admin_settings_hooks')) - response.mustcontain(no=['test_hooks_2']) - response.mustcontain(no=['cd /tmp2']) + self.app.post(route_path("admin_settings_hooks_delete"), params={"hook_id": hook_id, "csrf_token": csrf_token}) + response = self.app.get(route_path("admin_settings_hooks")) + response.mustcontain(no=["test_hooks_2"]) + response.mustcontain(no=["cd /tmp2"]) -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAdminSettingsGlobal(object): - def test_pre_post_code_code_active(self, csrf_token): - pre_code = 'rc-pre-code-187652122' - post_code = 'rc-postcode-98165231' + pre_code = "rc-pre-code-187652122" + post_code = "rc-postcode-98165231" - response = self.post_and_verify_settings({ - 'rhodecode_pre_code': pre_code, - 'rhodecode_post_code': post_code, - 'csrf_token': csrf_token, - }) + response = self.post_and_verify_settings( + { + "rhodecode_pre_code": pre_code, + "rhodecode_post_code": post_code, + "csrf_token": csrf_token, + } + ) response = response.follow() response.mustcontain(pre_code, post_code) def test_pre_post_code_code_inactive(self, csrf_token): - pre_code = 'rc-pre-code-187652122' - post_code = 'rc-postcode-98165231' - response = self.post_and_verify_settings({ - 'rhodecode_pre_code': '', - 'rhodecode_post_code': '', - 'csrf_token': csrf_token, - }) + pre_code = "rc-pre-code-187652122" + post_code = "rc-postcode-98165231" + response = self.post_and_verify_settings( + { + "rhodecode_pre_code": "", + "rhodecode_post_code": "", + "csrf_token": csrf_token, + } + ) response = response.follow() response.mustcontain(no=[pre_code, post_code]) def test_captcha_activate(self, csrf_token): - self.post_and_verify_settings({ - 'rhodecode_captcha_private_key': '1234567890', - 'rhodecode_captcha_public_key': '1234567890', - 'csrf_token': csrf_token, - }) + self.post_and_verify_settings( + { + "rhodecode_captcha_private_key": "1234567890", + "rhodecode_captcha_public_key": "1234567890", + "csrf_token": csrf_token, + } + ) - response = self.app.get(ADMIN_PREFIX + '/register') - response.mustcontain('captcha') + response = self.app.get(ADMIN_PREFIX + "/register") + response.mustcontain("captcha") def test_captcha_deactivate(self, csrf_token): - self.post_and_verify_settings({ - 'rhodecode_captcha_private_key': '', - 'rhodecode_captcha_public_key': '1234567890', - 'csrf_token': csrf_token, - }) + self.post_and_verify_settings( + { + "rhodecode_captcha_private_key": "", + "rhodecode_captcha_public_key": "1234567890", + "csrf_token": csrf_token, + } + ) - response = self.app.get(ADMIN_PREFIX + '/register') - response.mustcontain(no=['captcha']) + response = self.app.get(ADMIN_PREFIX + "/register") + response.mustcontain(no=["captcha"]) def test_title_change(self, csrf_token): - old_title = 'RhodeCode' + old_title = "RhodeCode" - for new_title in ['Changed', 'Żółwik', old_title]: - response = self.post_and_verify_settings({ - 'rhodecode_title': new_title, - 'csrf_token': csrf_token, - }) + for new_title in ["Changed", "Żółwik", old_title]: + response = self.post_and_verify_settings( + { + "rhodecode_title": new_title, + "csrf_token": csrf_token, + } + ) response = response.follow() response.mustcontain(new_title) def post_and_verify_settings(self, settings): - old_title = 'RhodeCode' - old_realm = 'RhodeCode authentication' + old_title = "RhodeCode" + old_realm = "RhodeCode authentication" params = { - 'rhodecode_title': old_title, - 'rhodecode_realm': old_realm, - 'rhodecode_pre_code': '', - 'rhodecode_post_code': '', - 'rhodecode_captcha_private_key': '', - 'rhodecode_captcha_public_key': '', - 'rhodecode_create_personal_repo_group': False, - 'rhodecode_personal_repo_group_pattern': '${username}', + "rhodecode_title": old_title, + "rhodecode_realm": old_realm, + "rhodecode_pre_code": "", + "rhodecode_post_code": "", + "rhodecode_captcha_private_key": "", + "rhodecode_captcha_public_key": "", + "rhodecode_create_personal_repo_group": False, + "rhodecode_personal_repo_group_pattern": "${username}", } params.update(settings) - response = self.app.post( - route_path('admin_settings_global_update'), params=params) + response = self.app.post(route_path("admin_settings_global_update"), params=params) - assert_session_flash(response, 'Updated application settings') + assert_session_flash(response, "Updated application settings") app_settings = SettingsModel().get_all_settings() - del settings['csrf_token'] + del settings["csrf_token"] for key, value in settings.items(): assert app_settings[key] == value return response -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAdminSettingsVcs(object): - def test_contains_svn_default_patterns(self): - response = self.app.get(route_path('admin_settings_vcs')) + response = self.app.get(route_path("admin_settings_vcs")) expected_patterns = [ - '/trunk', - '/branches/*', - '/tags/*', + "/trunk", + "/branches/*", + "/tags/*", ] for pattern in expected_patterns: response.mustcontain(pattern) - def test_add_new_svn_branch_and_tag_pattern( - self, backend_svn, form_defaults, disable_sql_cache, - csrf_token): - form_defaults.update({ - 'new_svn_branch': '/exp/branches/*', - 'new_svn_tag': '/important_tags/*', - 'csrf_token': csrf_token, - }) + def test_add_new_svn_branch_and_tag_pattern(self, backend_svn, form_defaults, disable_sql_cache, csrf_token): + form_defaults.update( + { + "new_svn_branch": "/exp/branches/*", + "new_svn_tag": "/important_tags/*", + "csrf_token": csrf_token, + } + ) - response = self.app.post( - route_path('admin_settings_vcs_update'), - params=form_defaults, status=302) + response = self.app.post(route_path("admin_settings_vcs_update"), params=form_defaults, status=302) response = response.follow() # Expect to find the new values on the page - response.mustcontain('/exp/branches/*') - response.mustcontain('/important_tags/*') + response.mustcontain("/exp/branches/*") + response.mustcontain("/important_tags/*") # Expect that those patterns are used to match branches and tags now - repo = backend_svn['svn-simple-layout'].scm_instance() - assert 'exp/branches/exp-sphinx-docs' in repo.branches - assert 'important_tags/v0.5' in repo.tags + repo = backend_svn["svn-simple-layout"].scm_instance() + assert "exp/branches/exp-sphinx-docs" in repo.branches + assert "important_tags/v0.5" in repo.tags - def test_add_same_svn_value_twice_shows_an_error_message( - self, form_defaults, csrf_token, settings_util): - settings_util.create_rhodecode_ui('vcs_svn_branch', '/test') - settings_util.create_rhodecode_ui('vcs_svn_tag', '/test') + def test_add_same_svn_value_twice_shows_an_error_message(self, form_defaults, csrf_token, settings_util): + settings_util.create_rhodecode_ui("vcs_svn_branch", "/test") + settings_util.create_rhodecode_ui("vcs_svn_tag", "/test") response = self.app.post( - route_path('admin_settings_vcs_update'), + route_path("admin_settings_vcs_update"), params={ - 'paths_root_path': form_defaults['paths_root_path'], - 'new_svn_branch': '/test', - 'new_svn_tag': '/test', - 'csrf_token': csrf_token, + "paths_root_path": form_defaults["paths_root_path"], + "new_svn_branch": "/test", + "new_svn_tag": "/test", + "csrf_token": csrf_token, }, - status=200) + status=200, + ) response.mustcontain("Pattern already exists") response.mustcontain("Some form inputs contain invalid data.") - @pytest.mark.parametrize('section', [ - 'vcs_svn_branch', - 'vcs_svn_tag', - ]) - def test_delete_svn_patterns( - self, section, csrf_token, settings_util): - setting = settings_util.create_rhodecode_ui( - section, '/test_delete', cleanup=False) + @pytest.mark.parametrize( + "section", + [ + "vcs_svn_branch", + "vcs_svn_tag", + ], + ) + def test_delete_svn_patterns(self, section, csrf_token, settings_util): + setting = settings_util.create_rhodecode_ui(section, "/test_delete", cleanup=False) self.app.post( - route_path('admin_settings_vcs_svn_pattern_delete'), - params={ - 'delete_svn_pattern': setting.ui_id, - 'csrf_token': csrf_token}, - headers={'X-REQUESTED-WITH': 'XMLHttpRequest'}) + route_path("admin_settings_vcs_svn_pattern_delete"), + params={"delete_svn_pattern": setting.ui_id, "csrf_token": csrf_token}, + headers={"X-REQUESTED-WITH": "XMLHttpRequest"}, + ) - @pytest.mark.parametrize('section', [ - 'vcs_svn_branch', - 'vcs_svn_tag', - ]) - def test_delete_svn_patterns_raises_404_when_no_xhr( - self, section, csrf_token, settings_util): - setting = settings_util.create_rhodecode_ui(section, '/test_delete') + @pytest.mark.parametrize( + "section", + [ + "vcs_svn_branch", + "vcs_svn_tag", + ], + ) + def test_delete_svn_patterns_raises_404_when_no_xhr(self, section, csrf_token, settings_util): + setting = settings_util.create_rhodecode_ui(section, "/test_delete") self.app.post( - route_path('admin_settings_vcs_svn_pattern_delete'), - params={ - 'delete_svn_pattern': setting.ui_id, - 'csrf_token': csrf_token}, - status=404) + route_path("admin_settings_vcs_svn_pattern_delete"), + params={"delete_svn_pattern": setting.ui_id, "csrf_token": csrf_token}, + status=404, + ) def test_extensions_hgevolve(self, form_defaults, csrf_token): - form_defaults.update({ - 'csrf_token': csrf_token, - 'extensions_evolve': 'True', - }) - response = self.app.post( - route_path('admin_settings_vcs_update'), - params=form_defaults, - status=302) + form_defaults.update( + { + "csrf_token": csrf_token, + "extensions_evolve": "True", + } + ) + response = self.app.post(route_path("admin_settings_vcs_update"), params=form_defaults, status=302) response = response.follow() extensions_input = ( - '') + '' + ) response.mustcontain(extensions_input) def test_has_a_section_for_pull_request_settings(self): - response = self.app.get(route_path('admin_settings_vcs')) - response.mustcontain('Pull Request Settings') + response = self.app.get(route_path("admin_settings_vcs")) + response.mustcontain("Pull Request Settings") def test_has_an_input_for_invalidation_of_inline_comments(self): - response = self.app.get(route_path('admin_settings_vcs')) + response = self.app.get(route_path("admin_settings_vcs")) assert_response = response.assert_response() - assert_response.one_element_exists( - '[name=rhodecode_use_outdated_comments]') + assert_response.one_element_exists("[name=rhodecode_use_outdated_comments]") - @pytest.mark.parametrize('new_value', [True, False]) - def test_allows_to_change_invalidation_of_inline_comments( - self, form_defaults, csrf_token, new_value): - setting_key = 'use_outdated_comments' - setting = SettingsModel().create_or_update_setting( - setting_key, not new_value, 'bool') + @pytest.mark.parametrize("new_value", [True, False]) + def test_allows_to_change_invalidation_of_inline_comments(self, form_defaults, csrf_token, new_value): + setting_key = "use_outdated_comments" + setting = SettingsModel().create_or_update_setting(setting_key, not new_value, "bool") Session().add(setting) Session().commit() - form_defaults.update({ - 'csrf_token': csrf_token, - 'rhodecode_use_outdated_comments': str(new_value), - }) - response = self.app.post( - route_path('admin_settings_vcs_update'), - params=form_defaults, - status=302) + form_defaults.update( + { + "csrf_token": csrf_token, + "rhodecode_use_outdated_comments": str(new_value), + } + ) + response = self.app.post(route_path("admin_settings_vcs_update"), params=form_defaults, status=302) response = response.follow() setting = SettingsModel().get_setting_by_name(setting_key) assert setting.app_settings_value is new_value - @pytest.mark.parametrize('new_value', [True, False]) - def test_allows_to_change_hg_rebase_merge_strategy( - self, form_defaults, csrf_token, new_value): - setting_key = 'hg_use_rebase_for_merging' + @pytest.mark.parametrize("new_value", [True, False]) + def test_allows_to_change_hg_rebase_merge_strategy(self, form_defaults, csrf_token, new_value): + setting_key = "hg_use_rebase_for_merging" - form_defaults.update({ - 'csrf_token': csrf_token, - 'rhodecode_' + setting_key: str(new_value), - }) + form_defaults.update( + { + "csrf_token": csrf_token, + "rhodecode_" + setting_key: str(new_value), + } + ) - with mock.patch.dict( - rhodecode.CONFIG, {'labs_settings_active': 'true'}): - self.app.post( - route_path('admin_settings_vcs_update'), - params=form_defaults, - status=302) + with mock.patch.dict(rhodecode.CONFIG, {"labs_settings_active": "true"}): + self.app.post(route_path("admin_settings_vcs_update"), params=form_defaults, status=302) setting = SettingsModel().get_setting_by_name(setting_key) assert setting.app_settings_value is new_value @@ -325,89 +318,76 @@ class TestAdminSettingsVcs(object): @pytest.fixture() def disable_sql_cache(self, request): # patch _do_orm_execute so it returns None similar like if we don't use a cached query - patcher = mock.patch( - 'rhodecode.lib.caching_query.ORMCache._do_orm_execute', return_value=None) + patcher = mock.patch("rhodecode.lib.caching_query.ORMCache._do_orm_execute", return_value=None) request.addfinalizer(patcher.stop) patcher.start() @pytest.fixture() def form_defaults(self): from rhodecode.apps.admin.views.settings import AdminSettingsView + return AdminSettingsView._form_defaults() # TODO: johbo: What we really want is to checkpoint before a test run and # reset the session afterwards. - @pytest.fixture(scope='class', autouse=True) + @pytest.fixture(scope="class", autouse=True) def cleanup_settings(self, request, baseapp): ui_id = RhodeCodeUi.ui_id original_ids = [r.ui_id for r in RhodeCodeUi.query().with_entities(ui_id)] @request.addfinalizer def cleanup(): - RhodeCodeUi.query().filter( - ui_id.notin_(original_ids)).delete(False) + RhodeCodeUi.query().filter(ui_id.notin_(original_ids)).delete(False) -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestLabsSettings(object): def test_get_settings_page_disabled(self): - with mock.patch.dict( - rhodecode.CONFIG, {'labs_settings_active': 'false'}): + with mock.patch.dict(rhodecode.CONFIG, {"labs_settings_active": "false"}): + response = self.app.get(route_path("admin_settings_labs"), status=302) - response = self.app.get( - route_path('admin_settings_labs'), status=302) - - assert response.location.endswith(route_path('admin_settings')) + assert response.location.endswith(route_path("admin_settings")) def test_get_settings_page_enabled(self): from rhodecode.apps.admin.views import settings + lab_settings = [ settings.LabSetting( - key='rhodecode_bool', - type='bool', - group='bool group', - label='bool label', - help='bool help' + key="rhodecode_bool", type="bool", group="bool group", label="bool label", help="bool help" ), settings.LabSetting( - key='rhodecode_text', - type='unicode', - group='text group', - label='text label', - help='text help' + key="rhodecode_text", type="unicode", group="text group", label="text label", help="text help" ), ] - with mock.patch.dict(rhodecode.CONFIG, - {'labs_settings_active': 'true'}): - with mock.patch.object(settings, '_LAB_SETTINGS', lab_settings): - response = self.app.get(route_path('admin_settings_labs')) + with mock.patch.dict(rhodecode.CONFIG, {"labs_settings_active": "true"}): + with mock.patch.object(settings, "_LAB_SETTINGS", lab_settings): + response = self.app.get(route_path("admin_settings_labs")) - assert '' in response + assert "" in response assert '' in response assert '

bool help

' in response assert 'name="rhodecode_bool" type="checkbox"' in response - assert '' in response + assert "" in response assert '' in response assert '

text help

' in response assert 'name="rhodecode_text" size="60" type="text"' in response -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestOpenSourceLicenses(object): - def test_records_are_displayed(self, autologin_user): sample_licenses = [ { "license": [ { - "fullName": "BSD 4-clause \"Original\" or \"Old\" License", + "fullName": 'BSD 4-clause "Original" or "Old" License', "shortName": "bsdOriginal", "spdxId": "BSD-4-Clause", - "url": "http://spdx.org/licenses/BSD-4-Clause.html" + "url": "http://spdx.org/licenses/BSD-4-Clause.html", } ], - "name": "python2.7-coverage-3.7.1" + "name": "python2.7-coverage-3.7.1", }, { "license": [ @@ -415,157 +395,124 @@ class TestOpenSourceLicenses(object): "fullName": "MIT License", "shortName": "mit", "spdxId": "MIT", - "url": "http://spdx.org/licenses/MIT.html" + "url": "http://spdx.org/licenses/MIT.html", } ], - "name": "python2.7-bootstrapped-pip-9.0.1" + "name": "python2.7-bootstrapped-pip-9.0.1", }, ] read_licenses_patch = mock.patch( - 'rhodecode.apps.admin.views.open_source_licenses.read_opensource_licenses', - return_value=sample_licenses) + "rhodecode.apps.admin.views.open_source_licenses.read_opensource_licenses", return_value=sample_licenses + ) with read_licenses_patch: - response = self.app.get( - route_path('admin_settings_open_source'), status=200) + response = self.app.get(route_path("admin_settings_open_source"), status=200) assert_response = response.assert_response() - assert_response.element_contains( - '.panel-heading', 'Licenses of Third Party Packages') + assert_response.element_contains(".panel-heading", "Licenses of Third Party Packages") for license_data in sample_licenses: response.mustcontain(license_data["license"][0]["spdxId"]) - assert_response.element_contains('.panel-body', license_data["name"]) + assert_response.element_contains(".panel-body", license_data["name"]) def test_records_can_be_read(self, autologin_user): - response = self.app.get( - route_path('admin_settings_open_source'), status=200) + response = self.app.get(route_path("admin_settings_open_source"), status=200) assert_response = response.assert_response() - assert_response.element_contains( - '.panel-heading', 'Licenses of Third Party Packages') + assert_response.element_contains(".panel-heading", "Licenses of Third Party Packages") def test_forbidden_when_normal_user(self, autologin_regular_user): - self.app.get( - route_path('admin_settings_open_source'), status=404) + self.app.get(route_path("admin_settings_open_source"), status=404) -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestUserSessions(object): - def test_forbidden_when_normal_user(self, autologin_regular_user): - self.app.get(route_path('admin_settings_sessions'), status=404) + self.app.get(route_path("admin_settings_sessions"), status=404) def test_show_sessions_page(self, autologin_user): - response = self.app.get(route_path('admin_settings_sessions'), status=200) - response.mustcontain('file') + response = self.app.get(route_path("admin_settings_sessions"), status=200) + response.mustcontain("file") def test_cleanup_old_sessions(self, autologin_user, csrf_token): - - post_data = { - 'csrf_token': csrf_token, - 'expire_days': '60' - } - response = self.app.post( - route_path('admin_settings_sessions_cleanup'), params=post_data, - status=302) - assert_session_flash(response, 'Cleaned up old sessions') + post_data = {"csrf_token": csrf_token, "expire_days": "60"} + response = self.app.post(route_path("admin_settings_sessions_cleanup"), params=post_data, status=302) + assert_session_flash(response, "Cleaned up old sessions") -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestAdminSystemInfo(object): - def test_forbidden_when_normal_user(self, autologin_regular_user): - self.app.get(route_path('admin_settings_system'), status=404) + self.app.get(route_path("admin_settings_system"), status=404) def test_system_info_page(self, autologin_user): - response = self.app.get(route_path('admin_settings_system')) - response.mustcontain('RhodeCode Community Edition, version {}'.format( - rhodecode.__version__)) + response = self.app.get(route_path("admin_settings_system")) + response.mustcontain("RhodeCode Community Edition, version {}".format(rhodecode.__version__)) def test_system_update_new_version(self, autologin_user): update_data = { - 'versions': [ - { - 'version': '100.0.0', - 'general': 'The latest version we are ever going to ship' - }, - { - 'version': '0.0.0', - 'general': 'The first version we ever shipped' - } + "versions": [ + {"version": "100.0.0", "general": "The latest version we are ever going to ship"}, + {"version": "0.0.0", "general": "The first version we ever shipped"}, ] } with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data): - response = self.app.get(route_path('admin_settings_system_update')) - response.mustcontain('A new version is available') + response = self.app.get(route_path("admin_settings_system_update")) + response.mustcontain("A new version is available") def test_system_update_nothing_new(self, autologin_user): - update_data = { - 'versions': [ - { - 'version': '4.0.0', - 'general': 'The first version we ever shipped' - } - ] - } + update_data = {"versions": [{"version": "4.0.0", "general": "The first version we ever shipped"}]} text = f"Your current version, {rhodecode.__version__}, is up-to-date as it is equal to or newer than the latest available version, 4.0.0." with mock.patch(UPDATE_DATA_QUALNAME, return_value=update_data): - response = self.app.get(route_path('admin_settings_system_update')) + response = self.app.get(route_path("admin_settings_system_update")) response.mustcontain(text) def test_system_update_bad_response(self, autologin_user): - with mock.patch(UPDATE_DATA_QUALNAME, side_effect=ValueError('foo')): - response = self.app.get(route_path('admin_settings_system_update')) - response.mustcontain( - 'Bad data sent from update server') + with mock.patch(UPDATE_DATA_QUALNAME, side_effect=ValueError("foo")): + response = self.app.get(route_path("admin_settings_system_update")) + response.mustcontain("Bad data sent from update server") @pytest.mark.usefixtures("app") class TestAdminSettingsIssueTracker(object): - RC_PREFIX = 'rhodecode_' - SHORT_PATTERN_KEY = 'issuetracker_pat_' + RC_PREFIX = "rhodecode_" + SHORT_PATTERN_KEY = "issuetracker_pat_" PATTERN_KEY = RC_PREFIX + SHORT_PATTERN_KEY - DESC_KEY = RC_PREFIX + 'issuetracker_desc_' + DESC_KEY = RC_PREFIX + "issuetracker_desc_" def test_issuetracker_index(self, autologin_user): - response = self.app.get(route_path('admin_settings_issuetracker')) + response = self.app.get(route_path("admin_settings_issuetracker")) assert response.status_code == 200 - def test_add_empty_issuetracker_pattern( - self, request, autologin_user, csrf_token): - post_url = route_path('admin_settings_issuetracker_update') - post_data = { - 'csrf_token': csrf_token - } + def test_add_empty_issuetracker_pattern(self, request, autologin_user, csrf_token): + post_url = route_path("admin_settings_issuetracker_update") + post_data = {"csrf_token": csrf_token} self.app.post(post_url, post_data, status=302) - def test_add_issuetracker_pattern( - self, request, autologin_user, csrf_token): - pattern = 'issuetracker_pat' - another_pattern = pattern+'1' - post_url = route_path('admin_settings_issuetracker_update') + def test_add_issuetracker_pattern(self, request, autologin_user, csrf_token): + pattern = "issuetracker_pat" + another_pattern = pattern + "1" + post_url = route_path("admin_settings_issuetracker_update") post_data = { - 'new_pattern_pattern_0': pattern, - 'new_pattern_url_0': 'http://url', - 'new_pattern_prefix_0': 'prefix', - 'new_pattern_description_0': 'description', - 'new_pattern_pattern_1': another_pattern, - 'new_pattern_url_1': 'https://url1', - 'new_pattern_prefix_1': 'prefix1', - 'new_pattern_description_1': 'description1', - 'csrf_token': csrf_token + "new_pattern_pattern_0": pattern, + "new_pattern_url_0": "http://url", + "new_pattern_prefix_0": "prefix", + "new_pattern_description_0": "description", + "new_pattern_pattern_1": another_pattern, + "new_pattern_url_1": "https://url1", + "new_pattern_prefix_1": "prefix1", + "new_pattern_description_1": "description1", + "csrf_token": csrf_token, } self.app.post(post_url, post_data, status=302) settings = SettingsModel().get_all_settings() self.uid = md5_safe(pattern) - assert settings[self.PATTERN_KEY+self.uid] == pattern + assert settings[self.PATTERN_KEY + self.uid] == pattern self.another_uid = md5_safe(another_pattern) - assert settings[self.PATTERN_KEY+self.another_uid] == another_pattern + assert settings[self.PATTERN_KEY + self.another_uid] == another_pattern @request.addfinalizer def cleanup(): defaults = SettingsModel().get_all_settings() - entries = [name for name in defaults if ( - (self.uid in name) or (self.another_uid in name))] + entries = [name for name in defaults if ((self.uid in name) or (self.another_uid in name))] start = len(self.RC_PREFIX) for del_key in entries: # TODO: anderson: get_by_name needs name without prefix @@ -574,71 +521,65 @@ class TestAdminSettingsIssueTracker(object): Session().commit() - def test_edit_issuetracker_pattern( - self, autologin_user, backend, csrf_token, request): - - old_pattern = 'issuetracker_pat1' + def test_edit_issuetracker_pattern(self, autologin_user, backend, csrf_token, request): + old_pattern = "issuetracker_pat1" old_uid = md5_safe(old_pattern) - post_url = route_path('admin_settings_issuetracker_update') + post_url = route_path("admin_settings_issuetracker_update") post_data = { - 'new_pattern_pattern_0': old_pattern, - 'new_pattern_url_0': 'http://url', - 'new_pattern_prefix_0': 'prefix', - 'new_pattern_description_0': 'description', - - 'csrf_token': csrf_token + "new_pattern_pattern_0": old_pattern, + "new_pattern_url_0": "http://url", + "new_pattern_prefix_0": "prefix", + "new_pattern_description_0": "description", + "csrf_token": csrf_token, } self.app.post(post_url, post_data, status=302) - new_pattern = 'issuetracker_pat1_edited' + new_pattern = "issuetracker_pat1_edited" self.new_uid = md5_safe(new_pattern) - post_url = route_path('admin_settings_issuetracker_update') + post_url = route_path("admin_settings_issuetracker_update") post_data = { - 'new_pattern_pattern_{}'.format(old_uid): new_pattern, - 'new_pattern_url_{}'.format(old_uid): 'https://url_edited', - 'new_pattern_prefix_{}'.format(old_uid): 'prefix_edited', - 'new_pattern_description_{}'.format(old_uid): 'description_edited', - 'uid': old_uid, - 'csrf_token': csrf_token + "new_pattern_pattern_{}".format(old_uid): new_pattern, + "new_pattern_url_{}".format(old_uid): "https://url_edited", + "new_pattern_prefix_{}".format(old_uid): "prefix_edited", + "new_pattern_description_{}".format(old_uid): "description_edited", + "uid": old_uid, + "csrf_token": csrf_token, } self.app.post(post_url, post_data, status=302) settings = SettingsModel().get_all_settings() - assert settings[self.PATTERN_KEY+self.new_uid] == new_pattern - assert settings[self.DESC_KEY + self.new_uid] == 'description_edited' - assert self.PATTERN_KEY+old_uid not in settings + assert settings[self.PATTERN_KEY + self.new_uid] == new_pattern + assert settings[self.DESC_KEY + self.new_uid] == "description_edited" + assert self.PATTERN_KEY + old_uid not in settings @request.addfinalizer def cleanup(): IssueTrackerSettingsModel().delete_entries(old_uid) IssueTrackerSettingsModel().delete_entries(self.new_uid) - def test_replace_issuetracker_pattern_description( - self, autologin_user, csrf_token, request, settings_util): - prefix = 'issuetracker' - pattern = 'issuetracker_pat' + def test_replace_issuetracker_pattern_description(self, autologin_user, csrf_token, request, settings_util): + prefix = "issuetracker" + pattern = "issuetracker_pat" self.uid = md5_safe(pattern) - pattern_key = '_'.join([prefix, 'pat', self.uid]) - rc_pattern_key = '_'.join(['rhodecode', pattern_key]) - desc_key = '_'.join([prefix, 'desc', self.uid]) - rc_desc_key = '_'.join(['rhodecode', desc_key]) - new_description = 'new_description' + pattern_key = "_".join([prefix, "pat", self.uid]) + rc_pattern_key = "_".join(["rhodecode", pattern_key]) + desc_key = "_".join([prefix, "desc", self.uid]) + rc_desc_key = "_".join(["rhodecode", desc_key]) + new_description = "new_description" - settings_util.create_rhodecode_setting( - pattern_key, pattern, 'unicode', cleanup=False) - settings_util.create_rhodecode_setting( - desc_key, 'old description', 'unicode', cleanup=False) + settings_util.create_rhodecode_setting(pattern_key, pattern, "unicode", cleanup=False) + settings_util.create_rhodecode_setting(desc_key, "old description", "unicode", cleanup=False) - post_url = route_path('admin_settings_issuetracker_update') + post_url = route_path("admin_settings_issuetracker_update") post_data = { - 'new_pattern_pattern_0': pattern, - 'new_pattern_url_0': 'https://url', - 'new_pattern_prefix_0': 'prefix', - 'new_pattern_description_0': new_description, - 'uid': self.uid, - 'csrf_token': csrf_token + "new_pattern_pattern_0": pattern, + "new_pattern_url_0": "https://url", + "new_pattern_prefix_0": "prefix", + "new_pattern_description_0": new_description, + "uid": self.uid, + "csrf_token": csrf_token, } self.app.post(post_url, post_data, status=302) settings = SettingsModel().get_all_settings() @@ -649,29 +590,23 @@ class TestAdminSettingsIssueTracker(object): def cleanup(): IssueTrackerSettingsModel().delete_entries(self.uid) - def test_delete_issuetracker_pattern( - self, autologin_user, backend, csrf_token, settings_util, xhr_header): - - old_pattern = 'issuetracker_pat_deleted' + def test_delete_issuetracker_pattern(self, autologin_user, backend, csrf_token, settings_util, xhr_header): + old_pattern = "issuetracker_pat_deleted" old_uid = md5_safe(old_pattern) - post_url = route_path('admin_settings_issuetracker_update') + post_url = route_path("admin_settings_issuetracker_update") post_data = { - 'new_pattern_pattern_0': old_pattern, - 'new_pattern_url_0': 'http://url', - 'new_pattern_prefix_0': 'prefix', - 'new_pattern_description_0': 'description', - - 'csrf_token': csrf_token + "new_pattern_pattern_0": old_pattern, + "new_pattern_url_0": "http://url", + "new_pattern_prefix_0": "prefix", + "new_pattern_description_0": "description", + "csrf_token": csrf_token, } self.app.post(post_url, post_data, status=302) - post_url = route_path('admin_settings_issuetracker_delete') - post_data = { - 'uid': old_uid, - 'csrf_token': csrf_token - } + post_url = route_path("admin_settings_issuetracker_delete") + post_data = {"uid": old_uid, "csrf_token": csrf_token} self.app.post(post_url, post_data, extra_environ=xhr_header, status=200) settings = SettingsModel().get_all_settings() - assert self.PATTERN_KEY+old_uid not in settings + assert self.PATTERN_KEY + old_uid not in settings assert self.DESC_KEY + old_uid not in settings diff --git a/rhodecode/apps/admin/tests/test_admin_user_groups.py b/rhodecode/apps/admin/tests/test_admin_user_groups.py index 73ab6017..378b2a14 100644 --- a/rhodecode/apps/admin/tests/test_admin_user_groups.py +++ b/rhodecode/apps/admin/tests/test_admin_user_groups.py @@ -21,8 +21,7 @@ import pytest from rhodecode.model.db import UserGroup, User from rhodecode.model.meta import Session -from rhodecode.tests import ( - TestController, assert_session_flash) +from rhodecode.tests import TestController, assert_session_flash from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -30,28 +29,26 @@ fixture = Fixture() class TestAdminUserGroupsView(TestController): - def test_show_users(self): self.log_user() - self.app.get(route_path('user_groups')) + self.app.get(route_path("user_groups")) def test_show_user_groups_data(self, xhr_header): self.log_user() - response = self.app.get(route_path( - 'user_groups_data'), extra_environ=xhr_header) + response = self.app.get(route_path("user_groups_data"), extra_environ=xhr_header) all_user_groups = UserGroup.query().count() - assert response.json['recordsTotal'] == all_user_groups + assert response.json["recordsTotal"] == all_user_groups def test_show_user_groups_data_filtered(self, xhr_header): self.log_user() - response = self.app.get(route_path( - 'user_groups_data', params={'search[value]': 'empty_search'}), - extra_environ=xhr_header) + response = self.app.get( + route_path("user_groups_data", params={"search[value]": "empty_search"}), extra_environ=xhr_header + ) all_user_groups = UserGroup.query().count() - assert response.json['recordsTotal'] == all_user_groups - assert response.json['recordsFiltered'] == 0 + assert response.json["recordsTotal"] == all_user_groups + assert response.json["recordsFiltered"] == 0 def test_usergroup_escape(self, user_util, xhr_header): self.log_user() @@ -68,84 +65,82 @@ class TestAdminUserGroupsView(TestController): user_group.users_group_name = xss_img user_group.user_group_description = 'DESC' - response = self.app.get( - route_path('user_groups_data'), extra_environ=xhr_header) + response = self.app.get(route_path("user_groups_data"), extra_environ=xhr_header) - response.mustcontain( - '<strong onload="alert();">DESC</strong>') - response.mustcontain( - '<img src="/image1" onload="' - 'alert('Hello, World!');">') + response.mustcontain("<strong onload="alert();">DESC</strong>") + response.mustcontain("<img src="/image1" onload="alert('Hello, World!');">") def test_edit_user_group_autocomplete_empty_members(self, xhr_header, user_util): self.log_user() ug = user_util.create_user_group() response = self.app.get( - route_path('user_group_members_data', user_group_id=ug.users_group_id), - extra_environ=xhr_header) + route_path("user_group_members_data", user_group_id=ug.users_group_id), extra_environ=xhr_header + ) - assert response.json == {'members': []} + assert response.json == {"members": []} def test_edit_user_group_autocomplete_members(self, xhr_header, user_util): self.log_user() members = [u.user_id for u in User.get_all()] ug = user_util.create_user_group(members=members) response = self.app.get( - route_path('user_group_members_data', - user_group_id=ug.users_group_id), - extra_environ=xhr_header) + route_path("user_group_members_data", user_group_id=ug.users_group_id), extra_environ=xhr_header + ) - assert len(response.json['members']) == len(members) + assert len(response.json["members"]) == len(members) def test_creation_page(self): self.log_user() - self.app.get(route_path('user_groups_new'), status=200) + self.app.get(route_path("user_groups_new"), status=200) def test_create(self): from rhodecode.lib import helpers as h self.log_user() - users_group_name = 'test_user_group' - response = self.app.post(route_path('user_groups_create'), { - 'users_group_name': users_group_name, - 'user_group_description': 'DESC', - 'active': True, - 'csrf_token': self.csrf_token}) + users_group_name = "test_user_group" + response = self.app.post( + route_path("user_groups_create"), + { + "users_group_name": users_group_name, + "user_group_description": "DESC", + "active": True, + "csrf_token": self.csrf_token, + }, + ) - user_group_id = UserGroup.get_by_group_name( - users_group_name).users_group_id + user_group_id = UserGroup.get_by_group_name(users_group_name).users_group_id - user_group_link = h.link_to( - users_group_name, - route_path('edit_user_group', user_group_id=user_group_id)) + user_group_link = h.link_to(users_group_name, route_path("edit_user_group", user_group_id=user_group_id)) - assert_session_flash( - response, - 'Created user group %s' % user_group_link) + assert_session_flash(response, "Created user group %s" % user_group_link) fixture.destroy_user_group(users_group_name) def test_create_with_empty_name(self): self.log_user() - response = self.app.post(route_path('user_groups_create'), { - 'users_group_name': '', - 'user_group_description': 'DESC', - 'active': True, - 'csrf_token': self.csrf_token}, status=200) + response = self.app.post( + route_path("user_groups_create"), + {"users_group_name": "", "user_group_description": "DESC", "active": True, "csrf_token": self.csrf_token}, + status=200, + ) - response.mustcontain('Please enter a value') + response.mustcontain("Please enter a value") def test_create_duplicate(self, user_util): self.log_user() user_group = user_util.create_user_group() duplicate_name = user_group.users_group_name - response = self.app.post(route_path('user_groups_create'), { - 'users_group_name': duplicate_name, - 'user_group_description': 'DESC', - 'active': True, - 'csrf_token': self.csrf_token}, status=200) + response = self.app.post( + route_path("user_groups_create"), + { + "users_group_name": duplicate_name, + "user_group_description": "DESC", + "active": True, + "csrf_token": self.csrf_token, + }, + status=200, + ) - response.mustcontain( - 'User group `{}` already exists'.format(duplicate_name)) + response.mustcontain("User group `{}` already exists".format(duplicate_name)) diff --git a/rhodecode/apps/admin/tests/test_admin_users.py b/rhodecode/apps/admin/tests/test_admin_users.py index 9e333b31..bef3d5b6 100644 --- a/rhodecode/apps/admin/tests/test_admin_users.py +++ b/rhodecode/apps/admin/tests/test_admin_users.py @@ -25,8 +25,7 @@ from rhodecode.model.db import User, UserApiKeys, UserEmailMap, Repository from rhodecode.model.meta import Session from rhodecode.model.user import UserModel -from rhodecode.tests import ( - TestController, TEST_USER_REGULAR_LOGIN, assert_session_flash) +from rhodecode.tests import TestController, TEST_USER_REGULAR_LOGIN, assert_session_flash from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -34,37 +33,31 @@ fixture = Fixture() class TestAdminUsersView(TestController): - def test_show_users(self): self.log_user() - self.app.get(route_path('users')) + self.app.get(route_path("users")) def test_show_users_data(self, xhr_header): self.log_user() - response = self.app.get(route_path( - 'users_data'), extra_environ=xhr_header) + response = self.app.get(route_path("users_data"), extra_environ=xhr_header) - all_users = User.query().filter( - User.username != User.DEFAULT_USER).count() - assert response.json['recordsTotal'] == all_users + all_users = User.query().filter(User.username != User.DEFAULT_USER).count() + assert response.json["recordsTotal"] == all_users def test_show_users_data_filtered(self, xhr_header): self.log_user() - response = self.app.get(route_path( - 'users_data', params={'search[value]': 'empty_search'}), - extra_environ=xhr_header) + response = self.app.get( + route_path("users_data", params={"search[value]": "empty_search"}), extra_environ=xhr_header + ) - all_users = User.query().filter( - User.username != User.DEFAULT_USER).count() - assert response.json['recordsTotal'] == all_users - assert response.json['recordsFiltered'] == 0 + all_users = User.query().filter(User.username != User.DEFAULT_USER).count() + assert response.json["recordsTotal"] == all_users + assert response.json["recordsFiltered"] == 0 def test_auth_tokens_default_user(self): self.log_user() user = User.get_default_user() - response = self.app.get( - route_path('edit_user_auth_tokens', user_id=user.user_id), - status=302) + response = self.app.get(route_path("edit_user_auth_tokens", user_id=user.user_id), status=302) def test_auth_tokens(self): self.log_user() @@ -72,27 +65,29 @@ class TestAdminUsersView(TestController): user = User.get_by_username(TEST_USER_REGULAR_LOGIN) user_id = user.user_id auth_tokens = user.auth_tokens - response = self.app.get( - route_path('edit_user_auth_tokens', user_id=user_id)) + response = self.app.get(route_path("edit_user_auth_tokens", user_id=user_id)) for token in auth_tokens: response.mustcontain(token[:4]) - response.mustcontain('never') + response.mustcontain("never") - @pytest.mark.parametrize("desc, lifetime", [ - ('forever', -1), - ('5mins', 60*5), - ('30days', 60*60*24*30), - ]) + @pytest.mark.parametrize( + "desc, lifetime", + [ + ("forever", -1), + ("5mins", 60 * 5), + ("30days", 60 * 60 * 24 * 30), + ], + ) def test_add_auth_token(self, desc, lifetime, user_util): self.log_user() user = user_util.create_user() user_id = user.user_id response = self.app.post( - route_path('edit_user_auth_tokens_add', user_id=user_id), - {'description': desc, 'lifetime': lifetime, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Auth token successfully created') + route_path("edit_user_auth_tokens_add", user_id=user_id), + {"description": desc, "lifetime": lifetime, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Auth token successfully created") response = response.follow() user = User.get(user_id) @@ -107,10 +102,10 @@ class TestAdminUsersView(TestController): assert 2 == len(keys) response = self.app.post( - route_path('edit_user_auth_tokens_add', user_id=user_id), - {'description': 'desc', 'lifetime': -1, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Auth token successfully created') + route_path("edit_user_auth_tokens_add", user_id=user_id), + {"description": "desc", "lifetime": -1, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Auth token successfully created") response.follow() # now delete our key @@ -118,47 +113,49 @@ class TestAdminUsersView(TestController): assert 3 == len(keys) response = self.app.post( - route_path('edit_user_auth_tokens_delete', user_id=user_id), - {'del_auth_token': keys[0].user_api_key_id, - 'csrf_token': self.csrf_token}) + route_path("edit_user_auth_tokens_delete", user_id=user_id), + {"del_auth_token": keys[0].user_api_key_id, "csrf_token": self.csrf_token}, + ) - assert_session_flash(response, 'Auth token successfully deleted') + assert_session_flash(response, "Auth token successfully deleted") keys = UserApiKeys.query().filter(UserApiKeys.user_id == user_id).all() assert 2 == len(keys) def test_ips(self): self.log_user() user = User.get_by_username(TEST_USER_REGULAR_LOGIN) - response = self.app.get(route_path('edit_user_ips', user_id=user.user_id)) - response.mustcontain('All IP addresses are allowed') + response = self.app.get(route_path("edit_user_ips", user_id=user.user_id)) + response.mustcontain("All IP addresses are allowed") - @pytest.mark.parametrize("test_name, ip, ip_range, failure", [ - ('127/24', '127.0.0.1/24', '127.0.0.0 - 127.0.0.255', False), - ('10/32', '10.0.0.10/32', '10.0.0.10 - 10.0.0.10', False), - ('0/16', '0.0.0.0/16', '0.0.0.0 - 0.0.255.255', False), - ('0/8', '0.0.0.0/8', '0.0.0.0 - 0.255.255.255', False), - ('127_bad_mask', '127.0.0.1/99', '127.0.0.1 - 127.0.0.1', True), - ('127_bad_ip', 'foobar', 'foobar', True), - ]) + @pytest.mark.parametrize( + "test_name, ip, ip_range, failure", + [ + ("127/24", "127.0.0.1/24", "127.0.0.0 - 127.0.0.255", False), + ("10/32", "10.0.0.10/32", "10.0.0.10 - 10.0.0.10", False), + ("0/16", "0.0.0.0/16", "0.0.0.0 - 0.0.255.255", False), + ("0/8", "0.0.0.0/8", "0.0.0.0 - 0.255.255.255", False), + ("127_bad_mask", "127.0.0.1/99", "127.0.0.1 - 127.0.0.1", True), + ("127_bad_ip", "foobar", "foobar", True), + ], + ) def test_ips_add(self, user_util, test_name, ip, ip_range, failure): self.log_user() user = user_util.create_user(username=test_name) user_id = user.user_id response = self.app.post( - route_path('edit_user_ips_add', user_id=user_id), - params={'new_ip': ip, 'csrf_token': self.csrf_token}) + route_path("edit_user_ips_add", user_id=user_id), params={"new_ip": ip, "csrf_token": self.csrf_token} + ) if failure: - assert_session_flash( - response, 'Please enter a valid IPv4 or IpV6 address') - response = self.app.get(route_path('edit_user_ips', user_id=user_id)) + assert_session_flash(response, "Please enter a valid IPv4 or IpV6 address") + response = self.app.get(route_path("edit_user_ips", user_id=user_id)) response.mustcontain(no=[ip]) response.mustcontain(no=[ip_range]) else: - response = self.app.get(route_path('edit_user_ips', user_id=user_id)) + response = self.app.get(route_path("edit_user_ips", user_id=user_id)) response.mustcontain(ip) response.mustcontain(ip_range) @@ -166,31 +163,31 @@ class TestAdminUsersView(TestController): self.log_user() user = user_util.create_user() user_id = user.user_id - ip = '127.0.0.1/32' - ip_range = '127.0.0.1 - 127.0.0.1' + ip = "127.0.0.1/32" + ip_range = "127.0.0.1 - 127.0.0.1" new_ip = UserModel().add_extra_ip(user_id, ip) Session().commit() new_ip_id = new_ip.ip_id - response = self.app.get(route_path('edit_user_ips', user_id=user_id)) + response = self.app.get(route_path("edit_user_ips", user_id=user_id)) response.mustcontain(ip) response.mustcontain(ip_range) self.app.post( - route_path('edit_user_ips_delete', user_id=user_id), - params={'del_ip_id': new_ip_id, 'csrf_token': self.csrf_token}) + route_path("edit_user_ips_delete", user_id=user_id), + params={"del_ip_id": new_ip_id, "csrf_token": self.csrf_token}, + ) - response = self.app.get(route_path('edit_user_ips', user_id=user_id)) - response.mustcontain('All IP addresses are allowed') + response = self.app.get(route_path("edit_user_ips", user_id=user_id)) + response.mustcontain("All IP addresses are allowed") response.mustcontain(no=[ip]) response.mustcontain(no=[ip_range]) def test_emails(self): self.log_user() user = User.get_by_username(TEST_USER_REGULAR_LOGIN) - response = self.app.get( - route_path('edit_user_emails', user_id=user.user_id)) - response.mustcontain('No additional emails specified') + response = self.app.get(route_path("edit_user_emails", user_id=user.user_id)) + response.mustcontain("No additional emails specified") def test_emails_add(self, user_util): self.log_user() @@ -198,13 +195,12 @@ class TestAdminUsersView(TestController): user_id = user.user_id self.app.post( - route_path('edit_user_emails_add', user_id=user_id), - params={'new_email': 'example@rhodecode.com', - 'csrf_token': self.csrf_token}) + route_path("edit_user_emails_add", user_id=user_id), + params={"new_email": "example@rhodecode.com", "csrf_token": self.csrf_token}, + ) - response = self.app.get( - route_path('edit_user_emails', user_id=user_id)) - response.mustcontain('example@rhodecode.com') + response = self.app.get(route_path("edit_user_emails", user_id=user_id)) + response.mustcontain("example@rhodecode.com") def test_emails_add_existing_email(self, user_util, user_regular): existing_email = user_regular.email @@ -214,14 +210,12 @@ class TestAdminUsersView(TestController): user_id = user.user_id response = self.app.post( - route_path('edit_user_emails_add', user_id=user_id), - params={'new_email': existing_email, - 'csrf_token': self.csrf_token}) - assert_session_flash( - response, 'This e-mail address is already taken') + route_path("edit_user_emails_add", user_id=user_id), + params={"new_email": existing_email, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "This e-mail address is already taken") - response = self.app.get( - route_path('edit_user_emails', user_id=user_id)) + response = self.app.get(route_path("edit_user_emails", user_id=user_id)) response.mustcontain(no=[existing_email]) def test_emails_delete(self, user_util): @@ -230,58 +224,58 @@ class TestAdminUsersView(TestController): user_id = user.user_id self.app.post( - route_path('edit_user_emails_add', user_id=user_id), - params={'new_email': 'example@rhodecode.com', - 'csrf_token': self.csrf_token}) + route_path("edit_user_emails_add", user_id=user_id), + params={"new_email": "example@rhodecode.com", "csrf_token": self.csrf_token}, + ) - response = self.app.get( - route_path('edit_user_emails', user_id=user_id)) - response.mustcontain('example@rhodecode.com') + response = self.app.get(route_path("edit_user_emails", user_id=user_id)) + response.mustcontain("example@rhodecode.com") - user_email = UserEmailMap.query()\ - .filter(UserEmailMap.email == 'example@rhodecode.com') \ - .filter(UserEmailMap.user_id == user_id)\ + user_email = ( + UserEmailMap.query() + .filter(UserEmailMap.email == "example@rhodecode.com") + .filter(UserEmailMap.user_id == user_id) .one() + ) del_email_id = user_email.email_id self.app.post( - route_path('edit_user_emails_delete', user_id=user_id), - params={'del_email_id': del_email_id, - 'csrf_token': self.csrf_token}) + route_path("edit_user_emails_delete", user_id=user_id), + params={"del_email_id": del_email_id, "csrf_token": self.csrf_token}, + ) - response = self.app.get( - route_path('edit_user_emails', user_id=user_id)) - response.mustcontain(no=['example@rhodecode.com']) + response = self.app.get(route_path("edit_user_emails", user_id=user_id)) + response.mustcontain(no=["example@rhodecode.com"]) def test_create(self, request, xhr_header): self.log_user() - username = 'newtestuser' - password = 'test12' + username = "newtestuser" + password = "test12" password_confirmation = password - name = 'name' - lastname = 'lastname' - email = 'mail@mail.com' + name = "name" + lastname = "lastname" + email = "mail@mail.com" - self.app.get(route_path('users_new')) + self.app.get(route_path("users_new")) - response = self.app.post(route_path('users_create'), params={ - 'username': username, - 'password': password, - 'description': 'mr CTO', - 'password_confirmation': password_confirmation, - 'firstname': name, - 'active': True, - 'lastname': lastname, - 'extern_name': 'rhodecode', - 'extern_type': 'rhodecode', - 'email': email, - 'csrf_token': self.csrf_token, - }) - user_link = h.link_to( - username, - route_path( - 'user_edit', user_id=User.get_by_username(username).user_id)) - assert_session_flash(response, 'Created user %s' % (user_link,)) + response = self.app.post( + route_path("users_create"), + params={ + "username": username, + "password": password, + "description": "mr CTO", + "password_confirmation": password_confirmation, + "firstname": name, + "active": True, + "lastname": lastname, + "extern_name": "rhodecode", + "extern_type": "rhodecode", + "email": email, + "csrf_token": self.csrf_token, + }, + ) + user_link = h.link_to(username, route_path("user_edit", user_id=User.get_by_username(username).user_id)) + assert_session_flash(response, "Created user %s" % (user_link,)) @request.addfinalizer def cleanup(): @@ -296,39 +290,38 @@ class TestAdminUsersView(TestController): assert new_user.lastname == lastname assert new_user.email == email - response = self.app.get(route_path('users_data'), - extra_environ=xhr_header) + response = self.app.get(route_path("users_data"), extra_environ=xhr_header) response.mustcontain(username) def test_create_err(self): self.log_user() - username = 'new_user' - password = '' - name = 'name' - lastname = 'lastname' - email = 'errmail.com' + username = "new_user" + password = "" + name = "name" + lastname = "lastname" + email = "errmail.com" - self.app.get(route_path('users_new')) + self.app.get(route_path("users_new")) - response = self.app.post(route_path('users_create'), params={ - 'username': username, - 'password': password, - 'name': name, - 'active': False, - 'lastname': lastname, - 'description': 'mr CTO', - 'email': email, - 'csrf_token': self.csrf_token, - }) + response = self.app.post( + route_path("users_create"), + params={ + "username": username, + "password": password, + "name": name, + "active": False, + "lastname": lastname, + "description": "mr CTO", + "email": email, + "csrf_token": self.csrf_token, + }, + ) - msg = u'Username "%(username)s" is forbidden' - msg = h.html_escape(msg % {'username': 'new_user'}) + msg = 'Username "%(username)s" is forbidden' + msg = h.html_escape(msg % {"username": "new_user"}) response.mustcontain('%s' % msg) - response.mustcontain( - 'Please enter a value') - response.mustcontain( - 'An email address must contain a' - ' single @') + response.mustcontain('Please enter a value') + response.mustcontain('An email address must contain a single @') def get_user(): Session().query(User).filter(User.username == username).one() @@ -338,343 +331,380 @@ class TestAdminUsersView(TestController): def test_new(self): self.log_user() - self.app.get(route_path('users_new')) + self.app.get(route_path("users_new")) - @pytest.mark.parametrize("name, attrs", [ - ('firstname', {'firstname': 'new_username'}), - ('lastname', {'lastname': 'new_username'}), - ('admin', {'admin': True}), - ('admin', {'admin': False}), - ('extern_type', {'extern_type': 'ldap'}), - ('extern_type', {'extern_type': None}), - ('extern_name', {'extern_name': 'test'}), - ('extern_name', {'extern_name': None}), - ('active', {'active': False}), - ('active', {'active': True}), - ('email', {'email': 'some@email.com'}), - ('language', {'language': 'de'}), - ('language', {'language': 'en'}), - ('description', {'description': 'hello CTO'}), - # ('new_password', {'new_password': 'foobar123', - # 'password_confirmation': 'foobar123'}) - ]) + @pytest.mark.parametrize( + "name, attrs", + [ + ("firstname", {"firstname": "new_username"}), + ("lastname", {"lastname": "new_username"}), + ("admin", {"admin": True}), + ("admin", {"admin": False}), + ("extern_type", {"extern_type": "ldap"}), + ("extern_type", {"extern_type": None}), + ("extern_name", {"extern_name": "test"}), + ("extern_name", {"extern_name": None}), + ("active", {"active": False}), + ("active", {"active": True}), + ("email", {"email": "some@email.com"}), + ("language", {"language": "de"}), + ("language", {"language": "en"}), + ("description", {"description": "hello CTO"}), + # ('new_password', {'new_password': 'foobar123', + # 'password_confirmation': 'foobar123'}) + ], + ) def test_update(self, name, attrs, user_util): self.log_user() usr = user_util.create_user( - password='qweqwe', - email='testme@rhodecode.org', - extern_type='rhodecode', - extern_name='xxx', + password="qweqwe", + email="testme@rhodecode.org", + extern_type="rhodecode", + extern_name="xxx", ) user_id = usr.user_id Session().commit() params = usr.get_api_data() - cur_lang = params['language'] or 'en' - params.update({ - 'password_confirmation': '', - 'new_password': '', - 'language': cur_lang, - 'csrf_token': self.csrf_token, - }) - params.update({'new_password': ''}) + cur_lang = params["language"] or "en" + params.update( + { + "password_confirmation": "", + "new_password": "", + "language": cur_lang, + "csrf_token": self.csrf_token, + } + ) + params.update({"new_password": ""}) params.update(attrs) - if name == 'email': - params['emails'] = [attrs['email']] - elif name == 'extern_type': + if name == "email": + params["emails"] = [attrs["email"]] + elif name == "extern_type": # cannot update this via form, expected value is original one - params['extern_type'] = "rhodecode" - elif name == 'extern_name': + params["extern_type"] = "rhodecode" + elif name == "extern_name": # cannot update this via form, expected value is original one - params['extern_name'] = 'xxx' + params["extern_name"] = "xxx" # special case since this user is not # logged in yet his data is not filled # so we use creation data - response = self.app.post( - route_path('user_update', user_id=usr.user_id), params) + response = self.app.post(route_path("user_update", user_id=usr.user_id), params) assert response.status_int == 302 - assert_session_flash(response, 'User updated successfully') + assert_session_flash(response, "User updated successfully") updated_user = User.get(user_id) updated_params = updated_user.get_api_data() - updated_params.update({'password_confirmation': ''}) - updated_params.update({'new_password': ''}) + updated_params.update({"password_confirmation": ""}) + updated_params.update({"new_password": ""}) - del params['csrf_token'] + del params["csrf_token"] assert params == updated_params - def test_update_and_migrate_password( - self, autologin_user, real_crypto_backend, user_util): - + def test_update_and_migrate_password(self, autologin_user, real_crypto_backend, user_util): user = user_util.create_user() temp_user = user.username - user.password = auth._RhodeCodeCryptoSha256().hash_create( - b'test123') + user.password = auth._RhodeCodeCryptoSha256().hash_create(b"test123") Session().add(user) Session().commit() params = user.get_api_data() - params.update({ - 'password_confirmation': 'qweqwe123', - 'new_password': 'qweqwe123', - 'language': 'en', - 'csrf_token': autologin_user.csrf_token, - }) + params.update( + { + "password_confirmation": "qweqwe123", + "new_password": "qweqwe123", + "language": "en", + "csrf_token": autologin_user.csrf_token, + } + ) - response = self.app.post( - route_path('user_update', user_id=user.user_id), params) + response = self.app.post(route_path("user_update", user_id=user.user_id), params) assert response.status_int == 302 - assert_session_flash(response, 'User updated successfully') + assert_session_flash(response, "User updated successfully") # new password should be bcrypted, after log-in and transfer user = User.get_by_username(temp_user) - assert user.password.startswith('$') + assert user.password.startswith("$") updated_user = User.get_by_username(temp_user) updated_params = updated_user.get_api_data() - updated_params.update({'password_confirmation': 'qweqwe123'}) - updated_params.update({'new_password': 'qweqwe123'}) + updated_params.update({"password_confirmation": "qweqwe123"}) + updated_params.update({"new_password": "qweqwe123"}) - del params['csrf_token'] + del params["csrf_token"] assert params == updated_params def test_delete(self): self.log_user() - username = 'newtestuserdeleteme' + username = "newtestuserdeleteme" fixture.create_user(name=username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), params={"csrf_token": self.csrf_token} + ) - assert_session_flash(response, 'Successfully deleted user `{}`'.format(username)) + assert_session_flash(response, "Successfully deleted user `{}`".format(username)) def test_delete_owner_of_repository(self, request, user_util): self.log_user() - obj_name = 'test_repo' + obj_name = "test_repo" usr = user_util.create_user() username = usr.username fixture.create_repo(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), params={"csrf_token": self.csrf_token} + ) - msg = 'user "%s" still owns 1 repositories and cannot be removed. ' \ - 'Switch owners or remove those repositories:%s' % (username, obj_name) + msg = ( + 'user "%s" still owns 1 repositories and cannot be removed. ' + "Switch owners or remove those repositories:%s" % (username, obj_name) + ) assert_session_flash(response, msg) fixture.destroy_repo(obj_name) def test_delete_owner_of_repository_detaching(self, request, user_util): self.log_user() - obj_name = 'test_repo' + obj_name = "test_repo" usr = user_util.create_user(auto_cleanup=False) username = usr.username fixture.create_repo(obj_name, cur_user=usr.username) Session().commit() - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'user_repos': 'detach', 'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), + params={"user_repos": "detach", "csrf_token": self.csrf_token}, + ) - msg = 'Detached 1 repositories' + msg = "Detached 1 repositories" assert_session_flash(response, msg) fixture.destroy_repo(obj_name) def test_delete_owner_of_repository_deleting(self, request, user_util): self.log_user() - obj_name = 'test_repo' + obj_name = "test_repo" usr = user_util.create_user(auto_cleanup=False) username = usr.username fixture.create_repo(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'user_repos': 'delete', 'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), + params={"user_repos": "delete", "csrf_token": self.csrf_token}, + ) - msg = 'Deleted 1 repositories' + msg = "Deleted 1 repositories" assert_session_flash(response, msg) def test_delete_owner_of_repository_group(self, request, user_util): self.log_user() - obj_name = 'test_group' + obj_name = "test_group" usr = user_util.create_user() username = usr.username fixture.create_repo_group(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), params={"csrf_token": self.csrf_token} + ) - msg = 'user "%s" still owns 1 repository groups and cannot be removed. ' \ - 'Switch owners or remove those repository groups:%s' % (username, obj_name) + msg = ( + 'user "%s" still owns 1 repository groups and cannot be removed. ' + "Switch owners or remove those repository groups:%s" % (username, obj_name) + ) assert_session_flash(response, msg) fixture.destroy_repo_group(obj_name) def test_delete_owner_of_repository_group_detaching(self, request, user_util): self.log_user() - obj_name = 'test_group' + obj_name = "test_group" usr = user_util.create_user(auto_cleanup=False) username = usr.username fixture.create_repo_group(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'user_repo_groups': 'delete', 'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), + params={"user_repo_groups": "delete", "csrf_token": self.csrf_token}, + ) - msg = 'Deleted 1 repository groups' + msg = "Deleted 1 repository groups" assert_session_flash(response, msg) def test_delete_owner_of_repository_group_deleting(self, request, user_util): self.log_user() - obj_name = 'test_group' + obj_name = "test_group" usr = user_util.create_user(auto_cleanup=False) username = usr.username fixture.create_repo_group(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'user_repo_groups': 'detach', 'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), + params={"user_repo_groups": "detach", "csrf_token": self.csrf_token}, + ) - msg = 'Detached 1 repository groups' + msg = "Detached 1 repository groups" assert_session_flash(response, msg) fixture.destroy_repo_group(obj_name) def test_delete_owner_of_user_group(self, request, user_util): self.log_user() - obj_name = 'test_user_group' + obj_name = "test_user_group" usr = user_util.create_user() username = usr.username fixture.create_user_group(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), params={"csrf_token": self.csrf_token} + ) - msg = 'user "%s" still owns 1 user groups and cannot be removed. ' \ - 'Switch owners or remove those user groups:%s' % (username, obj_name) + msg = ( + 'user "%s" still owns 1 user groups and cannot be removed. ' + "Switch owners or remove those user groups:%s" % (username, obj_name) + ) assert_session_flash(response, msg) fixture.destroy_user_group(obj_name) def test_delete_owner_of_user_group_detaching(self, request, user_util): self.log_user() - obj_name = 'test_user_group' + obj_name = "test_user_group" usr = user_util.create_user(auto_cleanup=False) username = usr.username fixture.create_user_group(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() try: response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'user_user_groups': 'detach', - 'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), + params={"user_user_groups": "detach", "csrf_token": self.csrf_token}, + ) - msg = 'Detached 1 user groups' + msg = "Detached 1 user groups" assert_session_flash(response, msg) finally: fixture.destroy_user_group(obj_name) def test_delete_owner_of_user_group_deleting(self, request, user_util): self.log_user() - obj_name = 'test_user_group' + obj_name = "test_user_group" usr = user_util.create_user(auto_cleanup=False) username = usr.username fixture.create_user_group(obj_name, cur_user=usr.username) - new_user = Session().query(User)\ - .filter(User.username == username).one() + new_user = Session().query(User).filter(User.username == username).one() response = self.app.post( - route_path('user_delete', user_id=new_user.user_id), - params={'user_user_groups': 'delete', 'csrf_token': self.csrf_token}) + route_path("user_delete", user_id=new_user.user_id), + params={"user_user_groups": "delete", "csrf_token": self.csrf_token}, + ) - msg = 'Deleted 1 user groups' + msg = "Deleted 1 user groups" assert_session_flash(response, msg) def test_edit(self, user_util): self.log_user() user = user_util.create_user() - self.app.get(route_path('user_edit', user_id=user.user_id)) + self.app.get(route_path("user_edit", user_id=user.user_id)) def test_edit_default_user_redirect(self): self.log_user() user = User.get_default_user() - self.app.get(route_path('user_edit', user_id=user.user_id), status=302) + self.app.get(route_path("user_edit", user_id=user.user_id), status=302) @pytest.mark.parametrize( - 'repo_create, repo_create_write, user_group_create, repo_group_create,' - 'fork_create, inherit_default_permissions, expect_error,' - 'expect_form_error', [ - ('hg.create.none', 'hg.create.write_on_repogroup.false', - 'hg.usergroup.create.false', 'hg.repogroup.create.false', - 'hg.fork.none', 'hg.inherit_default_perms.false', False, False), - ('hg.create.repository', 'hg.create.write_on_repogroup.false', - 'hg.usergroup.create.false', 'hg.repogroup.create.false', - 'hg.fork.none', 'hg.inherit_default_perms.false', False, False), - ('hg.create.repository', 'hg.create.write_on_repogroup.true', - 'hg.usergroup.create.true', 'hg.repogroup.create.true', - 'hg.fork.repository', 'hg.inherit_default_perms.false', False, - False), - ('hg.create.XXX', 'hg.create.write_on_repogroup.true', - 'hg.usergroup.create.true', 'hg.repogroup.create.true', - 'hg.fork.repository', 'hg.inherit_default_perms.false', False, - True), - ('', '', '', '', '', '', True, False), - ]) + "repo_create, repo_create_write, user_group_create, repo_group_create," + "fork_create, inherit_default_permissions, expect_error," + "expect_form_error", + [ + ( + "hg.create.none", + "hg.create.write_on_repogroup.false", + "hg.usergroup.create.false", + "hg.repogroup.create.false", + "hg.fork.none", + "hg.inherit_default_perms.false", + False, + False, + ), + ( + "hg.create.repository", + "hg.create.write_on_repogroup.false", + "hg.usergroup.create.false", + "hg.repogroup.create.false", + "hg.fork.none", + "hg.inherit_default_perms.false", + False, + False, + ), + ( + "hg.create.repository", + "hg.create.write_on_repogroup.true", + "hg.usergroup.create.true", + "hg.repogroup.create.true", + "hg.fork.repository", + "hg.inherit_default_perms.false", + False, + False, + ), + ( + "hg.create.XXX", + "hg.create.write_on_repogroup.true", + "hg.usergroup.create.true", + "hg.repogroup.create.true", + "hg.fork.repository", + "hg.inherit_default_perms.false", + False, + True, + ), + ("", "", "", "", "", "", True, False), + ], + ) def test_global_perms_on_user( - self, repo_create, repo_create_write, user_group_create, - repo_group_create, fork_create, expect_error, expect_form_error, - inherit_default_permissions, user_util): + self, + repo_create, + repo_create_write, + user_group_create, + repo_group_create, + fork_create, + expect_error, + expect_form_error, + inherit_default_permissions, + user_util, + ): self.log_user() user = user_util.create_user() uid = user.user_id # ENABLE REPO CREATE ON A GROUP perm_params = { - 'inherit_default_permissions': False, - 'default_repo_create': repo_create, - 'default_repo_create_on_write': repo_create_write, - 'default_user_group_create': user_group_create, - 'default_repo_group_create': repo_group_create, - 'default_fork_create': fork_create, - 'default_inherit_default_permissions': inherit_default_permissions, - 'csrf_token': self.csrf_token, + "inherit_default_permissions": False, + "default_repo_create": repo_create, + "default_repo_create_on_write": repo_create_write, + "default_user_group_create": user_group_create, + "default_repo_group_create": repo_group_create, + "default_fork_create": fork_create, + "default_inherit_default_permissions": inherit_default_permissions, + "csrf_token": self.csrf_token, } - response = self.app.post( - route_path('user_edit_global_perms_update', user_id=uid), - params=perm_params) + response = self.app.post(route_path("user_edit_global_perms_update", user_id=uid), params=perm_params) if expect_form_error: assert response.status_int == 200 - response.mustcontain('Value must be one of') + response.mustcontain("Value must be one of") else: if expect_error: - msg = 'An error occurred during permissions saving' + msg = "An error occurred during permissions saving" else: - msg = 'User global permissions updated successfully' + msg = "User global permissions updated successfully" ug = User.get(uid) - del perm_params['inherit_default_permissions'] - del perm_params['csrf_token'] + del perm_params["inherit_default_permissions"] + del perm_params["csrf_token"] assert perm_params == ug.get_default_perms() assert_session_flash(response, msg) @@ -682,45 +712,43 @@ class TestAdminUsersView(TestController): self.log_user() user = user_util.create_user() uid = user.user_id - response = self.app.get( - route_path('user_edit_global_perms', user_id=uid)) + response = self.app.get(route_path("user_edit_global_perms", user_id=uid)) default_user = User.get_default_user() default_permissions = default_user.get_default_perms() assert_response = response.assert_response() expected_permissions = ( - 'default_repo_create', 'default_repo_create_on_write', - 'default_fork_create', 'default_repo_group_create', - 'default_user_group_create', 'default_inherit_default_permissions') + "default_repo_create", + "default_repo_create_on_write", + "default_fork_create", + "default_repo_group_create", + "default_user_group_create", + "default_inherit_default_permissions", + ) for permission in expected_permissions: - css_selector = '[name={}][checked=checked]'.format(permission) + css_selector = "[name={}][checked=checked]".format(permission) element = assert_response.get_element(css_selector) assert element.value == default_permissions[permission] def test_perms_summary_page(self): user = self.log_user() - response = self.app.get( - route_path('edit_user_perms_summary', user_id=user['user_id'])) + response = self.app.get(route_path("edit_user_perms_summary", user_id=user["user_id"])) for repo in Repository.query().all(): response.mustcontain(repo.repo_name) def test_perms_summary_page_json(self): user = self.log_user() - response = self.app.get( - route_path('edit_user_perms_summary_json', user_id=user['user_id'])) + response = self.app.get(route_path("edit_user_perms_summary_json", user_id=user["user_id"])) for repo in Repository.query().all(): response.mustcontain(repo.repo_name) def test_audit_log_page(self): user = self.log_user() - self.app.get( - route_path('edit_user_audit_logs', user_id=user['user_id'])) + self.app.get(route_path("edit_user_audit_logs", user_id=user["user_id"])) def test_audit_log_page_download(self): user = self.log_user() - user_id = user['user_id'] - response = self.app.get( - route_path('edit_user_audit_logs_download', user_id=user_id)) + user_id = user["user_id"] + response = self.app.get(route_path("edit_user_audit_logs_download", user_id=user_id)) - assert response.content_disposition == \ - 'attachment; filename=user_{}_audit_logs.json'.format(user_id) + assert response.content_disposition == "attachment; filename=user_{}_audit_logs.json".format(user_id) assert response.content_type == "application/json" diff --git a/rhodecode/apps/admin/tests/test_admin_users_ssh_keys.py b/rhodecode/apps/admin/tests/test_admin_users_ssh_keys.py index 5ec3f4f7..38a02a67 100644 --- a/rhodecode/apps/admin/tests/test_admin_users_ssh_keys.py +++ b/rhodecode/apps/admin/tests/test_admin_users_ssh_keys.py @@ -37,22 +37,22 @@ class TestAdminUsersSshKeysView(TestController): qPFR5HyKTCHW0nFUJnZsbyFT5hMiF/hZkJc9A0ZbdSvJwCRQ/g3bmdL your_email@example.com """ - VALID_KEY = 'ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDk+77sjDzVeB6vev' \ - 'JsuZds1iNU5LANOa5CU5G/9JYIA6RYsWWMO7mbsR82IUckdqOHmxSy' \ - 'kfR1D1TdluyIpQLrwgH5kbn8FkVI8zBMCKakxowvN67B0R7b1BT4PP' \ - 'zW2JlOXei/m9W12ZY484VTow6/B+kf2Q8cP8tmCJmKWZma5Em7OTUh' \ - 'vjyQVNz3v7HfeY5Hq0Ci4ECJ59hepFDabJvtAXg9XrI6jvdphZTc30' \ - 'I4fG8+hBHzpeFxUGvSGNtXPUbwaAY8j/oHYrTpMgkj6pUEFsiKfC5zPq' \ - 'PFR5HyKTCHW0nFUJnZsbyFT5hMiF/hZkJc9A0ZbdSvJwCRQ/g3bmdL ' \ - 'your_email@example.com' - FINGERPRINT = 'MD5:01:4f:ad:29:22:6e:01:37:c9:d2:52:26:52:b0:2d:93' + VALID_KEY = ( + "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDk+77sjDzVeB6vev" + "JsuZds1iNU5LANOa5CU5G/9JYIA6RYsWWMO7mbsR82IUckdqOHmxSy" + "kfR1D1TdluyIpQLrwgH5kbn8FkVI8zBMCKakxowvN67B0R7b1BT4PP" + "zW2JlOXei/m9W12ZY484VTow6/B+kf2Q8cP8tmCJmKWZma5Em7OTUh" + "vjyQVNz3v7HfeY5Hq0Ci4ECJ59hepFDabJvtAXg9XrI6jvdphZTc30" + "I4fG8+hBHzpeFxUGvSGNtXPUbwaAY8j/oHYrTpMgkj6pUEFsiKfC5zPq" + "PFR5HyKTCHW0nFUJnZsbyFT5hMiF/hZkJc9A0ZbdSvJwCRQ/g3bmdL " + "your_email@example.com" + ) + FINGERPRINT = "MD5:01:4f:ad:29:22:6e:01:37:c9:d2:52:26:52:b0:2d:93" def test_ssh_keys_default_user(self): self.log_user() user = User.get_default_user() - self.app.get( - route_path('edit_user_ssh_keys', user_id=user.user_id), - status=302) + self.app.get(route_path("edit_user_ssh_keys", user_id=user.user_id), status=302) def test_add_ssh_key_error(self, user_util): self.log_user() @@ -61,13 +61,12 @@ class TestAdminUsersSshKeysView(TestController): key_data = self.INVALID_KEY - desc = 'MY SSH KEY' + desc = "MY SSH KEY" response = self.app.post( - route_path('edit_user_ssh_keys_add', user_id=user_id), - {'description': desc, 'key_data': key_data, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'An error occurred during ssh ' - 'key saving: Unable to decode the key') + route_path("edit_user_ssh_keys_add", user_id=user_id), + {"description": desc, "key_data": key_data, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "An error occurred during ssh key saving: Unable to decode the key") def test_ssh_key_duplicate(self, user_util): self.log_user() @@ -76,25 +75,23 @@ class TestAdminUsersSshKeysView(TestController): key_data = self.VALID_KEY - desc = 'MY SSH KEY' + desc = "MY SSH KEY" response = self.app.post( - route_path('edit_user_ssh_keys_add', user_id=user_id), - {'description': desc, 'key_data': key_data, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Ssh Key successfully created') + route_path("edit_user_ssh_keys_add", user_id=user_id), + {"description": desc, "key_data": key_data, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Ssh Key successfully created") response.follow() # flush session flash # add the same key AGAIN - desc = 'MY SSH KEY' + desc = "MY SSH KEY" response = self.app.post( - route_path('edit_user_ssh_keys_add', user_id=user_id), - {'description': desc, 'key_data': key_data, - 'csrf_token': self.csrf_token}) + route_path("edit_user_ssh_keys_add", user_id=user_id), + {"description": desc, "key_data": key_data, "csrf_token": self.csrf_token}, + ) - err = 'Such key with fingerprint `{}` already exists, ' \ - 'please use a different one'.format(self.FINGERPRINT) - assert_session_flash(response, 'An error occurred during ssh key ' - 'saving: {}'.format(err)) + err = "Such key with fingerprint `{}` already exists, please use a different one".format(self.FINGERPRINT) + assert_session_flash(response, "An error occurred during ssh key saving: {}".format(err)) def test_add_ssh_key(self, user_util): self.log_user() @@ -103,12 +100,12 @@ class TestAdminUsersSshKeysView(TestController): key_data = self.VALID_KEY - desc = 'MY SSH KEY' + desc = "MY SSH KEY" response = self.app.post( - route_path('edit_user_ssh_keys_add', user_id=user_id), - {'description': desc, 'key_data': key_data, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Ssh Key successfully created') + route_path("edit_user_ssh_keys_add", user_id=user_id), + {"description": desc, "key_data": key_data, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Ssh Key successfully created") response = response.follow() response.mustcontain(desc) @@ -120,12 +117,12 @@ class TestAdminUsersSshKeysView(TestController): key_data = self.VALID_KEY - desc = 'MY SSH KEY' + desc = "MY SSH KEY" response = self.app.post( - route_path('edit_user_ssh_keys_add', user_id=user_id), - {'description': desc, 'key_data': key_data, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Ssh Key successfully created') + route_path("edit_user_ssh_keys_add", user_id=user_id), + {"description": desc, "key_data": key_data, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Ssh Key successfully created") response = response.follow() # flush the Session flash # now delete our key @@ -133,11 +130,11 @@ class TestAdminUsersSshKeysView(TestController): assert 1 == len(keys) response = self.app.post( - route_path('edit_user_ssh_keys_delete', user_id=user_id), - {'del_ssh_key': keys[0].ssh_key_id, - 'csrf_token': self.csrf_token}) + route_path("edit_user_ssh_keys_delete", user_id=user_id), + {"del_ssh_key": keys[0].ssh_key_id, "csrf_token": self.csrf_token}, + ) - assert_session_flash(response, 'Ssh key successfully deleted') + assert_session_flash(response, "Ssh key successfully deleted") keys = UserSshKeys.query().filter(UserSshKeys.user_id == user_id).all() assert 0 == len(keys) @@ -146,9 +143,8 @@ class TestAdminUsersSshKeysView(TestController): user = user_util.create_user() user_id = user.user_id - response = self.app.get( - route_path('edit_user_ssh_keys_generate_keypair', user_id=user_id)) + response = self.app.get(route_path("edit_user_ssh_keys_generate_keypair", user_id=user_id)) - response.mustcontain('Private key') - response.mustcontain('Public key') - response.mustcontain('-----BEGIN PRIVATE KEY-----') + response.mustcontain("Private key") + response.mustcontain("Public key") + response.mustcontain("-----BEGIN PRIVATE KEY-----") diff --git a/rhodecode/apps/admin/views/artifacts.py b/rhodecode/apps/admin/views/artifacts.py index f6765eae..14147349 100644 --- a/rhodecode/apps/admin/views/artifacts.py +++ b/rhodecode/apps/admin/views/artifacts.py @@ -25,14 +25,13 @@ log = logging.getLogger(__name__) class AdminArtifactsView(BaseAppView, DataGridAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def artifacts(self): c = self.load_default_context() - c.active = 'artifacts' + c.active = "artifacts" return self._get_template_context(c) diff --git a/rhodecode/apps/admin/views/audit_logs.py b/rhodecode/apps/admin/views/audit_logs.py index b999c0af..79392ba7 100644 --- a/rhodecode/apps/admin/views/audit_logs.py +++ b/rhodecode/apps/admin/views/audit_logs.py @@ -31,22 +31,19 @@ log = logging.getLogger(__name__) class AdminAuditLogsView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def admin_audit_logs(self): c = self.load_default_context() - users_log = UserLog.query()\ - .options(joinedload(UserLog.user))\ - .options(joinedload(UserLog.repository)) + users_log = UserLog.query().options(joinedload(UserLog.user)).options(joinedload(UserLog.repository)) # FILTERING - c.search_term = self.request.GET.get('filter') + c.search_term = self.request.GET.get("filter") try: users_log = user_log_filter(users_log, c.search_term) except Exception: @@ -55,30 +52,30 @@ class AdminAuditLogsView(BaseAppView): users_log = users_log.order_by(UserLog.action_date.desc()) - p = safe_int(self.request.GET.get('page', 1), 1) + p = safe_int(self.request.GET.get("page", 1), 1) def url_generator(page_num): - query_params = { - 'page': page_num - } + query_params = {"page": page_num} if c.search_term: - query_params['filter'] = c.search_term + query_params["filter"] = c.search_term return self.request.current_route_path(_query=query_params) - c.audit_logs = SqlPage(users_log, page=p, items_per_page=10, - url_maker=url_generator) + c.audit_logs = SqlPage(users_log, page=p, items_per_page=10, url_maker=url_generator) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def admin_audit_log_entry(self): c = self.load_default_context() - audit_log_id = self.request.matchdict['audit_log_id'] + audit_log_id = self.request.matchdict["audit_log_id"] - c.audit_log_entry = UserLog.query()\ - .options(joinedload(UserLog.user))\ - .options(joinedload(UserLog.repository))\ - .filter(UserLog.user_log_id == audit_log_id).scalar() + c.audit_log_entry = ( + UserLog.query() + .options(joinedload(UserLog.user)) + .options(joinedload(UserLog.repository)) + .filter(UserLog.user_log_id == audit_log_id) + .scalar() + ) if not c.audit_log_entry: raise HTTPNotFound() diff --git a/rhodecode/apps/admin/views/automation.py b/rhodecode/apps/admin/views/automation.py index 1e6e0aff..5a58f90b 100644 --- a/rhodecode/apps/admin/views/automation.py +++ b/rhodecode/apps/admin/views/automation.py @@ -25,14 +25,13 @@ log = logging.getLogger(__name__) class AdminAutomationView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def automation(self): c = self.load_default_context() - c.active = 'automation' + c.active = "automation" return self._get_template_context(c) diff --git a/rhodecode/apps/admin/views/defaults.py b/rhodecode/apps/admin/views/defaults.py index c878cbad..a0532693 100644 --- a/rhodecode/apps/admin/views/defaults.py +++ b/rhodecode/apps/admin/views/defaults.py @@ -26,8 +26,7 @@ from pyramid.renderers import render from pyramid.response import Response from rhodecode.apps._base import BaseAppView -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.lib import helpers as h from rhodecode.model.forms import DefaultsForm from rhodecode.model.meta import Session @@ -38,37 +37,29 @@ log = logging.getLogger(__name__) class AdminDefaultSettingsView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def defaults_repository_show(self): c = self.load_default_context() c.backends = BACKENDS.keys() - c.active = 'repositories' + c.active = "repositories" defaults = SettingsModel().get_default_repo_settings() - data = render( - 'rhodecode:templates/admin/defaults/defaults.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/defaults/defaults.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def defaults_repository_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'repositories' + c.active = "repositories" form = DefaultsForm(self.request.translate)() try: @@ -77,25 +68,23 @@ class AdminDefaultSettingsView(BaseAppView): setting = SettingsModel().create_or_update_setting(k, v) Session().add(setting) Session().commit() - h.flash(_('Default settings updated successfully'), - category='success') + h.flash(_("Default settings updated successfully"), category="success") except formencode.Invalid as errors: data = render( - 'rhodecode:templates/admin/defaults/defaults.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/defaults/defaults.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: - log.exception('Exception in update action') - h.flash(_('Error occurred during update of default values'), - category='error') + log.exception("Exception in update action") + h.flash(_("Error occurred during update of default values"), category="error") - raise HTTPFound(h.route_path('admin_defaults_repositories')) + raise HTTPFound(h.route_path("admin_defaults_repositories")) diff --git a/rhodecode/apps/admin/views/exception_tracker.py b/rhodecode/apps/admin/views/exception_tracker.py index 1854b414..18fe70c1 100644 --- a/rhodecode/apps/admin/views/exception_tracker.py +++ b/rhodecode/apps/admin/views/exception_tracker.py @@ -23,8 +23,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import BaseAppView from rhodecode.apps._base.navigation import navigation_list from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.lib.utils2 import time_to_utcdatetime, safe_int from rhodecode.lib import exc_tracking @@ -41,10 +40,10 @@ class ExceptionsTrackerView(BaseAppView): exc_store_path = exc_tracking.get_exc_store() count = 0 for fname in os.listdir(exc_store_path): - parts = fname.split('_', 2) + parts = fname.split("_", 2) if not len(parts) == 3: continue - count +=1 + count += 1 return count def get_all_exceptions(self, read_metadata=False, limit=None, type_filter=None): @@ -53,20 +52,24 @@ class ExceptionsTrackerView(BaseAppView): def key_sorter(val): try: - return val.split('_')[-1] + return val.split("_")[-1] except Exception: return 0 for fname in reversed(sorted(os.listdir(exc_store_path), key=key_sorter)): - - parts = fname.split('_', 2) + parts = fname.split("_", 2) if not len(parts) == 3: continue exc_id, app_type, exc_timestamp = parts - exc = {'exc_id': exc_id, 'app_type': app_type, 'exc_type': 'unknown', - 'exc_utc_date': '', 'exc_timestamp': exc_timestamp} + exc = { + "exc_id": exc_id, + "app_type": app_type, + "exc_type": "unknown", + "exc_utc_date": "", + "exc_timestamp": exc_timestamp, + } if read_metadata: full_path = os.path.join(exc_store_path, fname) @@ -74,16 +77,16 @@ class ExceptionsTrackerView(BaseAppView): continue try: # we can read our metadata - with open(full_path, 'rb') as f: + with open(full_path, "rb") as f: exc_metadata = exc_tracking.exc_unserialize(f.read()) exc.update(exc_metadata) except Exception: - log.exception(f'Failed to read exc data from:{full_path}') + log.exception(f"Failed to read exc data from:{full_path}") pass # convert our timestamp to a date obj, for nicer representation - exc['exc_utc_date'] = time_to_utcdatetime(exc['exc_timestamp']) + exc["exc_utc_date"] = time_to_utcdatetime(exc["exc_timestamp"]) - type_present = exc.get('exc_type') + type_present = exc.get("exc_type") if type_filter: if type_present and type_present == type_filter: exception_list.append(exc) @@ -95,65 +98,64 @@ class ExceptionsTrackerView(BaseAppView): return exception_list @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def browse_exceptions(self): _ = self.request.translate c = self.load_default_context() - c.active = 'exceptions_browse' - c.limit = safe_int(self.request.GET.get('limit')) or 50 - c.type_filter = self.request.GET.get('type_filter') + c.active = "exceptions_browse" + c.limit = safe_int(self.request.GET.get("limit")) or 50 + c.type_filter = self.request.GET.get("type_filter") c.next_limit = c.limit + 50 - c.exception_list = self.get_all_exceptions( - read_metadata=True, limit=c.limit, type_filter=c.type_filter) + c.exception_list = self.get_all_exceptions(read_metadata=True, limit=c.limit, type_filter=c.type_filter) c.exception_list_count = self.count_all_exceptions() c.exception_store_dir = exc_tracking.get_exc_store() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def exception_show(self): _ = self.request.translate c = self.load_default_context() - c.active = 'exceptions' - c.exception_id = self.request.matchdict['exception_id'] + c.active = "exceptions" + c.exception_id = self.request.matchdict["exception_id"] c.traceback = exc_tracking.read_exception(c.exception_id, prefix=None) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def exception_delete_all(self): _ = self.request.translate c = self.load_default_context() - type_filter = self.request.POST.get('type_filter') + type_filter = self.request.POST.get("type_filter") - c.active = 'exceptions' + c.active = "exceptions" all_exc = self.get_all_exceptions(read_metadata=bool(type_filter), type_filter=type_filter) exc_count = 0 for exc in all_exc: if type_filter: - if exc.get('exc_type') == type_filter: - exc_tracking.delete_exception(exc['exc_id'], prefix=None) + if exc.get("exc_type") == type_filter: + exc_tracking.delete_exception(exc["exc_id"], prefix=None) exc_count += 1 else: - exc_tracking.delete_exception(exc['exc_id'], prefix=None) + exc_tracking.delete_exception(exc["exc_id"], prefix=None) exc_count += 1 - h.flash(_('Removed {} Exceptions').format(exc_count), category='success') - raise HTTPFound(h.route_path('admin_settings_exception_tracker')) + h.flash(_("Removed {} Exceptions").format(exc_count), category="success") + raise HTTPFound(h.route_path("admin_settings_exception_tracker")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def exception_delete(self): _ = self.request.translate c = self.load_default_context() - c.active = 'exceptions' - c.exception_id = self.request.matchdict['exception_id'] + c.active = "exceptions" + c.exception_id = self.request.matchdict["exception_id"] exc_tracking.delete_exception(c.exception_id, prefix=None) - h.flash(_('Removed Exception {}').format(c.exception_id), category='success') - raise HTTPFound(h.route_path('admin_settings_exception_tracker')) + h.flash(_("Removed Exception {}").format(c.exception_id), category="success") + raise HTTPFound(h.route_path("admin_settings_exception_tracker")) diff --git a/rhodecode/apps/admin/views/main_views.py b/rhodecode/apps/admin/views/main_views.py index 5fdee1c3..1f4d14d1 100644 --- a/rhodecode/apps/admin/views/main_views.py +++ b/rhodecode/apps/admin/views/main_views.py @@ -22,7 +22,7 @@ from pyramid.httpexceptions import HTTPFound, HTTPNotFound from rhodecode.apps._base import BaseAppView from rhodecode.lib import helpers as h -from rhodecode.lib.auth import (LoginRequired, NotAnonymous, HasRepoPermissionAny) +from rhodecode.lib.auth import LoginRequired, NotAnonymous, HasRepoPermissionAny from rhodecode.model.db import PullRequest @@ -38,7 +38,7 @@ class AdminMainView(BaseAppView): @NotAnonymous() def admin_main(self): c = self.load_default_context() - c.active = 'admin' + c.active = "admin" if not (c.is_super_admin or c.is_delegated_admin): raise HTTPNotFound() @@ -52,19 +52,15 @@ class AdminMainView(BaseAppView): pull_request_id: id of pull requests in the system """ - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) pull_request_id = pull_request.pull_request_id repo_name = pull_request.target_repo.repo_name # NOTE(marcink): # check permissions so we don't redirect to repo that we don't have access to # exposing it's name - target_repo_perm = HasRepoPermissionAny( - 'repository.read', 'repository.write', 'repository.admin')(repo_name) + target_repo_perm = HasRepoPermissionAny("repository.read", "repository.write", "repository.admin")(repo_name) if not target_repo_perm: raise HTTPNotFound() - raise HTTPFound( - h.route_path('pullrequest_show', repo_name=repo_name, - pull_request_id=pull_request_id)) + raise HTTPFound(h.route_path("pullrequest_show", repo_name=repo_name, pull_request_id=pull_request_id)) diff --git a/rhodecode/apps/admin/views/open_source_licenses.py b/rhodecode/apps/admin/views/open_source_licenses.py index 528a451a..b58560b2 100644 --- a/rhodecode/apps/admin/views/open_source_licenses.py +++ b/rhodecode/apps/admin/views/open_source_licenses.py @@ -21,24 +21,22 @@ import logging from rhodecode.apps._base import BaseAppView from rhodecode.apps._base.navigation import navigation_list -from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator from rhodecode.lib.utils import read_opensource_licenses log = logging.getLogger(__name__) class OpenSourceLicensesAdminSettingsView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def open_source_licenses(self): c = self.load_default_context() - c.active = 'open_source' + c.active = "open_source" c.navlist = navigation_list(self.request) - c.opensource_licenses = sorted( - read_opensource_licenses(), key=lambda d: d["name"]) + c.opensource_licenses = sorted(read_opensource_licenses(), key=lambda d: d["name"]) return self._get_template_context(c) diff --git a/rhodecode/apps/admin/views/permissions.py b/rhodecode/apps/admin/views/permissions.py index 35049bb8..1e6777e1 100644 --- a/rhodecode/apps/admin/views/permissions.py +++ b/rhodecode/apps/admin/views/permissions.py @@ -32,13 +32,10 @@ from rhodecode.apps.ssh_support.events import SshKeyFileChangeEvent from rhodecode import events from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.lib.utils2 import aslist, safe_str -from rhodecode.model.db import ( - or_, coalesce, User, UserIpMap, UserSshKeys) -from rhodecode.model.forms import ( - ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm) +from rhodecode.model.db import or_, coalesce, User, UserIpMap, UserSshKeys +from rhodecode.model.forms import ApplicationPermissionsForm, ObjectPermissionsForm, UserPermissionsForm from rhodecode.model.meta import Session from rhodecode.model.permission import PermissionModel from rhodecode.model.settings import SettingsModel @@ -50,122 +47,109 @@ log = logging.getLogger(__name__) class AdminPermissionsView(BaseAppView, DataGridAppView): def load_default_context(self): c = self._get_local_tmpl_context() - PermissionModel().set_global_permission_choices( - c, gettext_translator=self.request.translate) + PermissionModel().set_global_permission_choices(c, gettext_translator=self.request.translate) return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def permissions_application(self): c = self.load_default_context() - c.active = 'application' + c.active = "application" c.user = User.get_default_user(refresh=True) app_settings = c.rc_config defaults = { - 'anonymous': c.user.active, - 'default_register_message': app_settings.get( - 'rhodecode_register_message') + "anonymous": c.user.active, + "default_register_message": app_settings.get("rhodecode_register_message"), } defaults.update(c.user.get_default_perms()) - data = render('rhodecode:templates/admin/permissions/permissions.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + data = render( + "rhodecode:templates/admin/permissions/permissions.mako", self._get_template_context(c), self.request ) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def permissions_application_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'application' + c.active = "application" _form = ApplicationPermissionsForm( self.request.translate, [x[0] for x in c.register_choices], [x[0] for x in c.password_reset_choices], - [x[0] for x in c.extern_activate_choices])() + [x[0] for x in c.extern_activate_choices], + )() try: form_result = _form.to_python(dict(self.request.POST)) - form_result.update({'perm_user_name': User.DEFAULT_USER}) + form_result.update({"perm_user_name": User.DEFAULT_USER}) PermissionModel().update_application_permissions(form_result) settings = [ - ('register_message', 'default_register_message'), + ("register_message", "default_register_message"), ] for setting, form_key in settings: - sett = SettingsModel().create_or_update_setting( - setting, form_result[form_key]) + sett = SettingsModel().create_or_update_setting(setting, form_result[form_key]) Session().add(sett) Session().commit() - h.flash(_('Application permissions updated successfully'), - category='success') + h.flash(_("Application permissions updated successfully"), category="success") except formencode.Invalid as errors: defaults = errors.value data = render( - 'rhodecode:templates/admin/permissions/permissions.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/permissions/permissions.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=defaults, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: log.exception("Exception during update of permissions") - h.flash(_('Error occurred during update of permissions'), - category='error') + h.flash(_("Error occurred during update of permissions"), category="error") affected_user_ids = [User.get_default_user_id()] PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound(h.route_path('admin_permissions_application')) + raise HTTPFound(h.route_path("admin_permissions_application")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def permissions_objects(self): c = self.load_default_context() - c.active = 'objects' + c.active = "objects" c.user = User.get_default_user(refresh=True) defaults = {} defaults.update(c.user.get_default_perms()) data = render( - 'rhodecode:templates/admin/permissions/permissions.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + "rhodecode:templates/admin/permissions/permissions.mako", self._get_template_context(c), self.request ) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def permissions_objects_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'objects' + c.active = "objects" _form = ObjectPermissionsForm( self.request.translate, @@ -176,87 +160,75 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): try: form_result = _form.to_python(dict(self.request.POST)) - form_result.update({'perm_user_name': User.DEFAULT_USER}) + form_result.update({"perm_user_name": User.DEFAULT_USER}) PermissionModel().update_object_permissions(form_result) Session().commit() - h.flash(_('Object permissions updated successfully'), - category='success') + h.flash(_("Object permissions updated successfully"), category="success") except formencode.Invalid as errors: defaults = errors.value data = render( - 'rhodecode:templates/admin/permissions/permissions.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/permissions/permissions.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=defaults, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: log.exception("Exception during update of permissions") - h.flash(_('Error occurred during update of permissions'), - category='error') + h.flash(_("Error occurred during update of permissions"), category="error") affected_user_ids = [User.get_default_user_id()] PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound(h.route_path('admin_permissions_object')) + raise HTTPFound(h.route_path("admin_permissions_object")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def permissions_branch(self): c = self.load_default_context() - c.active = 'branch' + c.active = "branch" c.user = User.get_default_user(refresh=True) defaults = {} defaults.update(c.user.get_default_perms()) data = render( - 'rhodecode:templates/admin/permissions/permissions.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + "rhodecode:templates/admin/permissions/permissions.mako", self._get_template_context(c), self.request ) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def permissions_global(self): c = self.load_default_context() - c.active = 'global' + c.active = "global" c.user = User.get_default_user(refresh=True) defaults = {} defaults.update(c.user.get_default_perms()) data = render( - 'rhodecode:templates/admin/permissions/permissions.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + "rhodecode:templates/admin/permissions/permissions.mako", self._get_template_context(c), self.request ) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def permissions_global_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'global' + c.active = "global" _form = UserPermissionsForm( self.request.translate, @@ -265,71 +237,69 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): [x[0] for x in c.repo_group_create_choices], [x[0] for x in c.user_group_create_choices], [x[0] for x in c.fork_choices], - [x[0] for x in c.inherit_default_permission_choices])() + [x[0] for x in c.inherit_default_permission_choices], + )() try: form_result = _form.to_python(dict(self.request.POST)) - form_result.update({'perm_user_name': User.DEFAULT_USER}) + form_result.update({"perm_user_name": User.DEFAULT_USER}) PermissionModel().update_user_permissions(form_result) Session().commit() - h.flash(_('Global permissions updated successfully'), - category='success') + h.flash(_("Global permissions updated successfully"), category="success") except formencode.Invalid as errors: defaults = errors.value data = render( - 'rhodecode:templates/admin/permissions/permissions.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/permissions/permissions.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=defaults, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: log.exception("Exception during update of permissions") - h.flash(_('Error occurred during update of permissions'), - category='error') + h.flash(_("Error occurred during update of permissions"), category="error") affected_user_ids = [User.get_default_user_id()] PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound(h.route_path('admin_permissions_global')) + raise HTTPFound(h.route_path("admin_permissions_global")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def permissions_ips(self): c = self.load_default_context() - c.active = 'ips' + c.active = "ips" c.user = User.get_default_user(refresh=True) - c.user_ip_map = ( - UserIpMap.query().filter(UserIpMap.user == c.user).all()) + c.user_ip_map = UserIpMap.query().filter(UserIpMap.user == c.user).all() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def permissions_overview(self): c = self.load_default_context() - c.active = 'perms' + c.active = "perms" c.user = User.get_default_user(refresh=True) c.perm_user = c.user.AuthUser() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def auth_token_access(self): from rhodecode import CONFIG c = self.load_default_context() - c.active = 'auth_token_access' + c.active = "auth_token_access" c.user = User.get_default_user(refresh=True) c.perm_user = c.user.AuthUser() @@ -337,39 +307,36 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): mapper = self.request.registry.queryUtility(IRoutesMapper) c.view_data = [] - _argument_prog = re.compile(r'\{(.*?)\}|:\((.*)\)') + _argument_prog = re.compile(r"\{(.*?)\}|:\((.*)\)") introspector = self.request.registry.introspector view_intr = {} - for view_data in introspector.get_category('views'): - intr = view_data['introspectable'] + for view_data in introspector.get_category("views"): + intr = view_data["introspectable"] - if 'route_name' in intr and intr['attr']: - view_intr[intr['route_name']] = '{}:{}'.format( - str(intr['derived_callable'].__name__), intr['attr'] - ) + if "route_name" in intr and intr["attr"]: + view_intr[intr["route_name"]] = "{}:{}".format(str(intr["derived_callable"].__name__), intr["attr"]) - c.whitelist_key = 'api_access_controllers_whitelist' - c.whitelist_file = CONFIG.get('__file__') - whitelist_views = aslist( - CONFIG.get(c.whitelist_key), sep=',') + c.whitelist_key = "api_access_controllers_whitelist" + c.whitelist_file = CONFIG.get("__file__") + whitelist_views = aslist(CONFIG.get(c.whitelist_key), sep=",") for route_info in mapper.get_routes(): - if not route_info.name.startswith('__'): + if not route_info.name.startswith("__"): routepath = route_info.pattern def replace(matchobj): if matchobj.group(1): - return "{%s}" % matchobj.group(1).split(':')[0] + return "{%s}" % matchobj.group(1).split(":")[0] else: return "{%s}" % matchobj.group(2) routepath = _argument_prog.sub(replace, routepath) - if not routepath.startswith('/'): - routepath = '/' + routepath + if not routepath.startswith("/"): + routepath = "/" + routepath - view_fqn = view_intr.get(route_info.name, 'NOT AVAILABLE') + view_fqn = view_intr.get(route_info.name, "NOT AVAILABLE") active = view_fqn in whitelist_views c.view_data.append((route_info.name, view_fqn, routepath, active)) @@ -377,55 +344,51 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): return self._get_template_context(c) def ssh_enabled(self): - return self.request.registry.settings.get( - 'ssh.generate_authorized_keyfile') + return self.request.registry.settings.get("ssh.generate_authorized_keyfile") @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def ssh_keys(self): c = self.load_default_context() - c.active = 'ssh_keys' + c.active = "ssh_keys" c.ssh_enabled = self.ssh_enabled() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def ssh_keys_data(self): _ = self.request.translate self.load_default_context() - column_map = { - 'fingerprint': 'ssh_key_fingerprint', - 'username': User.username - } + column_map = {"fingerprint": "ssh_key_fingerprint", "username": User.username} draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) - ssh_keys_data_total_count = UserSshKeys.query()\ - .count() + ssh_keys_data_total_count = UserSshKeys.query().count() # json generate base_q = UserSshKeys.query().join(UserSshKeys.user) if search_q: - like_expression = f'%{safe_str(search_q)}%' - base_q = base_q.filter(or_( - User.username.ilike(like_expression), - UserSshKeys.ssh_key_fingerprint.ilike(like_expression), - )) + like_expression = f"%{safe_str(search_q)}%" + base_q = base_q.filter( + or_( + User.username.ilike(like_expression), + UserSshKeys.ssh_key_fingerprint.ilike(like_expression), + ) + ) users_data_total_filtered_count = base_q.count() sort_col = self._get_order_col(order_by, UserSshKeys) if sort_col: - if order_dir == 'asc': + if order_dir == "asc": # handle null values properly to order by NULL last - if order_by in ['created_on']: + if order_by in ["created_on"]: sort_col = coalesce(sort_col, datetime.date.max) sort_col = sort_col.asc() else: # handle null values properly to order by NULL last - if order_by in ['created_on']: + if order_by in ["created_on"]: sort_col = coalesce(sort_col, datetime.date.min) sort_col = sort_col.desc() @@ -436,42 +399,39 @@ class AdminPermissionsView(BaseAppView, DataGridAppView): ssh_keys_data = [] for ssh_key in ssh_keys: - ssh_keys_data.append({ - "username": h.gravatar_with_user(self.request, ssh_key.user.username), - "fingerprint": ssh_key.ssh_key_fingerprint, - "description": ssh_key.description, - "created_on": h.format_date(ssh_key.created_on), - "accessed_on": h.format_date(ssh_key.accessed_on), - "action": h.link_to( - _('Edit'), h.route_path('edit_user_ssh_keys', - user_id=ssh_key.user.user_id)) - }) + ssh_keys_data.append( + { + "username": h.gravatar_with_user(self.request, ssh_key.user.username), + "fingerprint": ssh_key.ssh_key_fingerprint, + "description": ssh_key.description, + "created_on": h.format_date(ssh_key.created_on), + "accessed_on": h.format_date(ssh_key.accessed_on), + "action": h.link_to(_("Edit"), h.route_path("edit_user_ssh_keys", user_id=ssh_key.user.user_id)), + } + ) - data = ({ - 'draw': draw, - 'data': ssh_keys_data, - 'recordsTotal': ssh_keys_data_total_count, - 'recordsFiltered': users_data_total_filtered_count, - }) + data = { + "draw": draw, + "data": ssh_keys_data, + "recordsTotal": ssh_keys_data_total_count, + "recordsFiltered": users_data_total_filtered_count, + } return data @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def ssh_keys_update(self): _ = self.request.translate self.load_default_context() ssh_enabled = self.ssh_enabled() - key_file = self.request.registry.settings.get( - 'ssh.authorized_keys_file_path') + key_file = self.request.registry.settings.get("ssh.authorized_keys_file_path") if ssh_enabled: events.trigger(SshKeyFileChangeEvent(), self.request.registry) - h.flash(_('Updated SSH keys file: {}').format(key_file), - category='success') + h.flash(_("Updated SSH keys file: {}").format(key_file), category="success") else: - h.flash(_('SSH key support is disabled in .ini file'), - category='warning') + h.flash(_("SSH key support is disabled in .ini file"), category="warning") - raise HTTPFound(h.route_path('admin_permissions_ssh_keys')) + raise HTTPFound(h.route_path("admin_permissions_ssh_keys")) diff --git a/rhodecode/apps/admin/views/process_management.py b/rhodecode/apps/admin/views/process_management.py index 4e2a019c..a37d2a2a 100644 --- a/rhodecode/apps/admin/views/process_management.py +++ b/rhodecode/apps/admin/views/process_management.py @@ -25,8 +25,7 @@ import signal from rhodecode.apps._base import BaseAppView from rhodecode.apps._base.navigation import navigation_list from rhodecode.lib import system_info -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.lib.utils2 import safe_int, StrictAttributeDict log = logging.getLogger(__name__) @@ -40,30 +39,29 @@ class AdminProcessManagementView(BaseAppView): def _format_proc(self, proc, with_children=False): try: mem = proc.memory_info() - proc_formatted = StrictAttributeDict({ - 'pid': proc.pid, - 'name': proc.name(), - 'mem_rss': mem.rss, - 'mem_vms': mem.vms, - 'cpu_percent': proc.cpu_percent(interval=0.1), - 'create_time': proc.create_time(), - 'cmd': ' '.join(proc.cmdline()), - }) + proc_formatted = StrictAttributeDict( + { + "pid": proc.pid, + "name": proc.name(), + "mem_rss": mem.rss, + "mem_vms": mem.vms, + "cpu_percent": proc.cpu_percent(interval=0.1), + "create_time": proc.create_time(), + "cmd": " ".join(proc.cmdline()), + } + ) if with_children: - proc_formatted.update({ - 'children': [self._format_proc(x) - for x in proc.children(recursive=True)] - }) + proc_formatted.update({"children": [self._format_proc(x) for x in proc.children(recursive=True)]}) except Exception: - log.exception('Failed to load proc') + log.exception("Failed to load proc") proc_formatted = None return proc_formatted def get_processes(self): proc_list = [] for p in psutil.process_iter(): - if 'gunicorn' in p.name(): + if "gunicorn" in p.name(): proc = self._format_proc(p, with_children=True) if proc: proc_list.append(proc) @@ -73,27 +71,27 @@ class AdminProcessManagementView(BaseAppView): def get_workers(self): workers = None try: - rc_config = system_info.rhodecode_config().value['config'] - workers = rc_config['server:main'].get('workers') + rc_config = system_info.rhodecode_config().value["config"] + workers = rc_config["server:main"].get("workers") except Exception: pass - return workers or '?' + return workers or "?" @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def process_management(self): _ = self.request.translate c = self.load_default_context() - c.active = 'process_management' + c.active = "process_management" c.navlist = navigation_list(self.request) c.gunicorn_processes = self.get_processes() c.gunicorn_workers = self.get_workers() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def process_management_data(self): _ = self.request.translate c = self.load_default_context() @@ -101,10 +99,10 @@ class AdminProcessManagementView(BaseAppView): return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def process_management_signal(self): - pids = self.request.json.get('pids', []) + pids = self.request.json.get("pids", []) result = [] def on_terminate(proc): @@ -122,7 +120,7 @@ class AdminProcessManagementView(BaseAppView): children = proc.children(recursive=True) if children: - log.warning('Wont kill Master Process') + log.warning("Wont kill Master Process") else: procs.append(proc) @@ -130,39 +128,39 @@ class AdminProcessManagementView(BaseAppView): try: p.terminate() except psutil.AccessDenied as e: - log.warning(f'Access denied: {e}') + log.warning(f"Access denied: {e}") gone, alive = psutil.wait_procs(procs, timeout=10, callback=on_terminate) for p in alive: try: p.kill() except psutil.AccessDenied as e: - log.warning(f'Access denied: {e}') + log.warning(f"Access denied: {e}") - return {'result': result} + return {"result": result} @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def process_management_master_signal(self): - pid_data = self.request.json.get('pid_data', {}) - pid = safe_int(pid_data['pid']) - action = pid_data['action'] + pid_data = self.request.json.get("pid_data", {}) + pid = safe_int(pid_data["pid"]) + action = pid_data["action"] if pid: try: proc = psutil.Process(pid) except psutil.NoSuchProcess: - return {'result': 'failure_no_such_process'} + return {"result": "failure_no_such_process"} children = proc.children(recursive=True) if children: # master process - if action == '+' and len(children) <= 20: + if action == "+" and len(children) <= 20: proc.send_signal(signal.SIGTTIN) - elif action == '-' and len(children) >= 2: + elif action == "-" and len(children) >= 2: proc.send_signal(signal.SIGTTOU) else: - return {'result': 'failure_wrong_action'} - return {'result': 'success'} + return {"result": "failure_wrong_action"} + return {"result": "success"} - return {'result': 'failure_not_master'} + return {"result": "failure_not_master"} diff --git a/rhodecode/apps/admin/views/repo_groups.py b/rhodecode/apps/admin/views/repo_groups.py index e06486b7..42a00099 100644 --- a/rhodecode/apps/admin/views/repo_groups.py +++ b/rhodecode/apps/admin/views/repo_groups.py @@ -31,23 +31,19 @@ from sqlalchemy.orm import aliased from rhodecode import events from rhodecode.apps._base import BaseAppView, DataGridAppView -from rhodecode.lib.auth import ( - LoginRequired, CSRFRequired, NotAnonymous, - HasPermissionAny, HasRepoGroupPermissionAny) +from rhodecode.lib.auth import LoginRequired, CSRFRequired, NotAnonymous, HasPermissionAny, HasRepoGroupPermissionAny from rhodecode.lib import helpers as h, audit_logger from rhodecode.lib.str_utils import safe_int, safe_str from rhodecode.model.forms import RepoGroupForm from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.scm import RepoGroupList -from rhodecode.model.db import ( - or_, count, func, in_filter_generator, Session, RepoGroup, User, Repository) +from rhodecode.model.db import or_, count, func, in_filter_generator, Session, RepoGroup, User, Repository log = logging.getLogger(__name__) class AdminRepoGroupsView(BaseAppView, DataGridAppView): - def load_default_context(self): c = self._get_local_tmpl_context() @@ -63,17 +59,14 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): # override the choices for this form, we need to filter choices # and display only those we have ADMIN right groups_with_admin_rights = RepoGroupList( - RepoGroup.query().all(), - perm_set=['group.admin'], extra_kwargs=dict(user=self._rhodecode_user)) - c.repo_groups = RepoGroup.groups_choices( - groups=groups_with_admin_rights, - show_empty_group=allow_empty_group) + RepoGroup.query().all(), perm_set=["group.admin"], extra_kwargs=dict(user=self._rhodecode_user) + ) + c.repo_groups = RepoGroup.groups_choices(groups=groups_with_admin_rights, show_empty_group=allow_empty_group) c.personal_repo_group = self._rhodecode_user.personal_repo_group def _can_create_repo_group(self, parent_group_id=None): - is_admin = HasPermissionAny('hg.admin')('group create controller') - create_repo_group = HasPermissionAny( - 'hg.repogroup.create.true')('group create controller') + is_admin = HasPermissionAny("hg.admin")("group create controller") + create_repo_group = HasPermissionAny("hg.repogroup.create.true")("group create controller") if is_admin or (create_repo_group and not parent_group_id): # we're global admin, or we have global repo group create # permission @@ -83,8 +76,7 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): # we check the permission if we can write to parent group group = RepoGroup.get(parent_group_id) group_name = group.group_name if group else None - if HasRepoGroupPermissionAny('group.admin')( - group_name, 'check if user is an admin of group'): + if HasRepoGroupPermissionAny("group.admin")(group_name, "check if user is an admin of group"): # we're an admin of passed in group, we're ok. return True else: @@ -105,85 +97,90 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): def repo_group_list_data(self): self.load_default_context() column_map = { - 'name': 'group_name_hash', - 'desc': 'group_description', - 'last_change': 'updated_on', - 'top_level_repos': 'repos_total', - 'owner': 'user_username', + "name": "group_name_hash", + "desc": "group_description", + "last_change": "updated_on", + "top_level_repos": "repos_total", + "owner": "user_username", } draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) - _render = self.request.get_partial_renderer( - 'rhodecode:templates/data_table/_dt_elements.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/data_table/_dt_elements.mako") c = _render.get_call_context() def quick_menu(repo_group_name): - return _render('quick_repo_group_menu', repo_group_name) + return _render("quick_repo_group_menu", repo_group_name) def repo_group_lnk(repo_group_name): - return _render('repo_group_name', repo_group_name) + return _render("repo_group_name", repo_group_name) def last_change(last_change): if isinstance(last_change, datetime.datetime) and not last_change.tzinfo: ts = time.time() - utc_offset = (datetime.datetime.fromtimestamp(ts) - - datetime.datetime.utcfromtimestamp(ts)).total_seconds() + utc_offset = ( + datetime.datetime.fromtimestamp(ts) - datetime.datetime.utcfromtimestamp(ts) + ).total_seconds() last_change = last_change + datetime.timedelta(seconds=utc_offset) return _render("last_change", last_change) def desc(desc, personal): - return _render( - 'repo_group_desc', desc, personal, c.visual.stylify_metatags) + return _render("repo_group_desc", desc, personal, c.visual.stylify_metatags) def repo_group_actions(repo_group_id, repo_group_name, gr_count): - return _render( - 'repo_group_actions', repo_group_id, repo_group_name, gr_count) + return _render("repo_group_actions", repo_group_id, repo_group_name, gr_count) def user_profile(username): - return _render('user_profile', username) + return _render("user_profile", username) - _perms = ['group.admin'] + _perms = ["group.admin"] allowed_ids = [-1] + self._rhodecode_user.repo_group_acl_ids_from_stack(_perms) - repo_groups_data_total_count = RepoGroup.query()\ - .filter(or_( - # generate multiple IN to fix limitation problems - *in_filter_generator(RepoGroup.group_id, allowed_ids) - )) \ + repo_groups_data_total_count = ( + RepoGroup.query() + .filter( + or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(RepoGroup.group_id, allowed_ids) + ) + ) .count() + ) - repo_groups_data_total_inactive_count = RepoGroup.query()\ - .filter(RepoGroup.group_id.in_(allowed_ids))\ - .count() + repo_groups_data_total_inactive_count = RepoGroup.query().filter(RepoGroup.group_id.in_(allowed_ids)).count() repo_count = count(Repository.repo_id) OwnerUser = aliased(User) - base_q = Session.query( - RepoGroup.group_name, - RepoGroup.group_name_hash, - RepoGroup.group_description, - RepoGroup.group_id, - RepoGroup.personal, - RepoGroup.updated_on, - OwnerUser.username.label('owner_username'), - repo_count.label('repos_count') - ) \ - .filter(or_( - # generate multiple IN to fix limitation problems - *in_filter_generator(RepoGroup.group_id, allowed_ids) - )) \ - .outerjoin(Repository, RepoGroup.group_id == Repository.group_id) \ - .join(OwnerUser, RepoGroup.user_id == OwnerUser.user_id) + base_q = ( + Session.query( + RepoGroup.group_name, + RepoGroup.group_name_hash, + RepoGroup.group_description, + RepoGroup.group_id, + RepoGroup.personal, + RepoGroup.updated_on, + OwnerUser.username.label("owner_username"), + repo_count.label("repos_count"), + ) + .filter( + or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(RepoGroup.group_id, allowed_ids) + ) + ) + .outerjoin(Repository, RepoGroup.group_id == Repository.group_id) + .join(OwnerUser, RepoGroup.user_id == OwnerUser.user_id) + ) base_q = base_q.group_by(RepoGroup, OwnerUser) if search_q: - like_expression = f'%{safe_str(search_q)}%' - base_q = base_q.filter(or_( - RepoGroup.group_name.ilike(like_expression), - )) + like_expression = f"%{safe_str(search_q)}%" + base_q = base_q.filter( + or_( + RepoGroup.group_name.ilike(like_expression), + ) + ) repo_groups_data_total_filtered_count = base_q.count() # the inactive isn't really used, but we still make it same as other data grids @@ -191,19 +188,19 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): repo_groups_data_total_filtered_inactive_count = repo_groups_data_total_filtered_count sort_defined = False - if order_by == 'group_name': + if order_by == "group_name": sort_col = func.lower(RepoGroup.group_name) sort_defined = True - elif order_by == 'repos_total': + elif order_by == "repos_total": sort_col = repo_count sort_defined = True - elif order_by == 'user_username': + elif order_by == "user_username": sort_col = OwnerUser.username else: sort_col = getattr(RepoGroup, order_by, None) if sort_defined or sort_col: - if order_dir == 'asc': + if order_dir == "asc": sort_col = sort_col.asc() else: sort_col = sort_col.desc() @@ -219,29 +216,25 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): row = { "menu": quick_menu(repo_gr.group_name), "name": repo_group_lnk(repo_gr.group_name), - "last_change": last_change(repo_gr.updated_on), - "last_changeset": "", "last_changeset_raw": "", - "desc": desc(repo_gr.group_description, repo_gr.personal), "owner": user_profile(repo_gr.owner_username), "top_level_repos": repo_gr.repos_count, - "action": repo_group_actions( - repo_gr.group_id, repo_gr.group_name, repo_gr.repos_count), + "action": repo_group_actions(repo_gr.group_id, repo_gr.group_name, repo_gr.repos_count), } repo_groups_data.append(row) - data = ({ - 'draw': draw, - 'data': repo_groups_data, - 'recordsTotal': repo_groups_data_total_count, - 'recordsTotalInactive': repo_groups_data_total_inactive_count, - 'recordsFiltered': repo_groups_data_total_filtered_count, - 'recordsFilteredInactive': repo_groups_data_total_filtered_inactive_count, - }) + data = { + "draw": draw, + "data": repo_groups_data, + "recordsTotal": repo_groups_data_total_count, + "recordsTotalInactive": repo_groups_data_total_inactive_count, + "recordsFiltered": repo_groups_data_total_filtered_count, + "recordsFilteredInactive": repo_groups_data_total_filtered_inactive_count, + } return data @@ -252,7 +245,7 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): c = self.load_default_context() # perm check for admin, create_group perm or admin of parent_group - parent_group_id = safe_int(self.request.GET.get('parent_group')) + parent_group_id = safe_int(self.request.GET.get("parent_group")) _gr = RepoGroup.get(parent_group_id) if not self._can_create_repo_group(parent_group_id): raise HTTPForbidden() @@ -261,7 +254,7 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): defaults = {} # Future proof for default of repo group - parent_group_choice = '-1' + parent_group_choice = "-1" if not self._rhodecode_user.is_admin and self._rhodecode_user.personal_repo_group: parent_group_choice = self._rhodecode_user.personal_repo_group @@ -269,18 +262,13 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): if parent_group_id in [x[0] for x in c.repo_groups]: parent_group_choice = safe_str(parent_group_id) - defaults.update({'group_parent_id': parent_group_choice}) + defaults.update({"group_parent_id": parent_group_choice}) data = render( - 'rhodecode:templates/admin/repo_groups/repo_group_add.mako', - self._get_template_context(c), self.request) - - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + "rhodecode:templates/admin/repo_groups/repo_group_add.mako", self._get_template_context(c), self.request ) + + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() @@ -291,7 +279,7 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): c = self.load_default_context() _ = self.request.translate - parent_group_id = safe_int(self.request.POST.get('group_parent_id')) + parent_group_id = safe_int(self.request.POST.get("group_parent_id")) can_create = self._can_create_repo_group(parent_group_id) self._load_form_data(c) @@ -299,58 +287,54 @@ class AdminRepoGroupsView(BaseAppView, DataGridAppView): # here in the Form available_groups = list(map(lambda k: safe_str(k[0]), c.repo_groups)) repo_group_form = RepoGroupForm( - self.request.translate, available_groups=available_groups, - can_create_in_root=can_create)() + self.request.translate, available_groups=available_groups, can_create_in_root=can_create + )() - repo_group_name = self.request.POST.get('group_name') + repo_group_name = self.request.POST.get("group_name") try: owner = self._rhodecode_user form_result = repo_group_form.to_python(dict(self.request.POST)) - copy_permissions = form_result.get('group_copy_permissions') + copy_permissions = form_result.get("group_copy_permissions") repo_group = RepoGroupModel().create( - group_name=form_result['group_name_full'], - group_description=form_result['group_description'], + group_name=form_result["group_name_full"], + group_description=form_result["group_description"], owner=owner.user_id, - copy_permissions=form_result['group_copy_permissions'] + copy_permissions=form_result["group_copy_permissions"], ) Session().flush() repo_group_data = repo_group.get_api_data() audit_logger.store_web( - 'repo_group.create', action_data={'data': repo_group_data}, - user=self._rhodecode_user) + "repo_group.create", action_data={"data": repo_group_data}, user=self._rhodecode_user + ) Session().commit() - _new_group_name = form_result['group_name_full'] + _new_group_name = form_result["group_name_full"] repo_group_url = h.link_to( - _new_group_name, - h.route_path('repo_group_home', repo_group_name=_new_group_name)) - h.flash(h.literal(_('Created repository group %s') - % repo_group_url), category='success') + _new_group_name, h.route_path("repo_group_home", repo_group_name=_new_group_name) + ) + h.flash(h.literal(_("Created repository group %s") % repo_group_url), category="success") except formencode.Invalid as errors: data = render( - 'rhodecode:templates/admin/repo_groups/repo_group_add.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/repo_groups/repo_group_add.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: log.exception("Exception during creation of repository group") - h.flash(_('Error occurred during creation of repository group %s') - % repo_group_name, category='error') - raise HTTPFound(h.route_path('home')) + h.flash(_("Error occurred during creation of repository group %s") % repo_group_name, category="error") + raise HTTPFound(h.route_path("home")) PermissionModel().trigger_permission_flush() - raise HTTPFound( - h.route_path('repo_group_home', - repo_group_name=form_result['group_name_full'])) + raise HTTPFound(h.route_path("repo_group_home", repo_group_name=form_result["group_name_full"])) diff --git a/rhodecode/apps/admin/views/repositories.py b/rhodecode/apps/admin/views/repositories.py index ed49c945..1a49832d 100644 --- a/rhodecode/apps/admin/views/repositories.py +++ b/rhodecode/apps/admin/views/repositories.py @@ -30,9 +30,7 @@ from rhodecode import events from rhodecode.apps._base import BaseAppView, DataGridAppView from rhodecode.lib.celerylib.utils import get_task_id -from rhodecode.lib.auth import ( - LoginRequired, CSRFRequired, NotAnonymous, - HasPermissionAny, HasRepoGroupPermissionAny) +from rhodecode.lib.auth import LoginRequired, CSRFRequired, NotAnonymous, HasPermissionAny, HasRepoGroupPermissionAny from rhodecode.lib import helpers as h from rhodecode.lib.utils import repo_name_slug from rhodecode.lib.utils2 import safe_int, safe_str @@ -41,21 +39,18 @@ from rhodecode.model.permission import PermissionModel from rhodecode.model.repo import RepoModel from rhodecode.model.scm import RepoList, RepoGroupList, ScmModel from rhodecode.model.settings import SettingsModel -from rhodecode.model.db import ( - in_filter_generator, or_, func, Session, Repository, RepoGroup, User) +from rhodecode.model.db import in_filter_generator, or_, func, Session, Repository, RepoGroup, User log = logging.getLogger(__name__) class AdminReposView(BaseAppView, DataGridAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c def _load_form_data(self, c): - acl_groups = RepoGroupList(RepoGroup.query().all(), - perm_set=['group.write', 'group.admin']) + acl_groups = RepoGroupList(RepoGroup.query().all(), perm_set=["group.write", "group.admin"]) c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) c.repo_groups_choices = list(map(lambda k: safe_str(k[0]), c.repo_groups)) c.personal_repo_group = self._rhodecode_user.personal_repo_group @@ -73,69 +68,78 @@ class AdminReposView(BaseAppView, DataGridAppView): def repository_list_data(self): self.load_default_context() column_map = { - 'name': 'repo_name', - 'desc': 'description', - 'last_change': 'updated_on', - 'owner': 'user_username', + "name": "repo_name", + "desc": "description", + "last_change": "updated_on", + "owner": "user_username", } draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) - _perms = ['repository.admin'] + _perms = ["repository.admin"] allowed_ids = [-1] + self._rhodecode_user.repo_acl_ids_from_stack(_perms) - repos_data_total_count = Repository.query() \ - .filter(or_( - # generate multiple IN to fix limitation problems - *in_filter_generator(Repository.repo_id, allowed_ids)) - ) \ + repos_data_total_count = ( + Repository.query() + .filter( + or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(Repository.repo_id, allowed_ids) + ) + ) .count() + ) RepoFork = aliased(Repository) OwnerUser = aliased(User) - base_q = Session.query( - Repository.repo_id, - Repository.repo_name, - Repository.description, - Repository.repo_type, - Repository.repo_state, - Repository.private, - Repository.archived, - Repository.updated_on, - Repository._changeset_cache, - RepoFork.repo_name.label('fork_repo_name'), - OwnerUser.username.label('owner_username'), - ) \ - .filter(or_( - # generate multiple IN to fix limitation problems - *in_filter_generator(Repository.repo_id, allowed_ids)) - ) \ - .outerjoin(RepoFork, Repository.fork_id == RepoFork.repo_id) \ + base_q = ( + Session.query( + Repository.repo_id, + Repository.repo_name, + Repository.description, + Repository.repo_type, + Repository.repo_state, + Repository.private, + Repository.archived, + Repository.updated_on, + Repository._changeset_cache, + RepoFork.repo_name.label("fork_repo_name"), + OwnerUser.username.label("owner_username"), + ) + .filter( + or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(Repository.repo_id, allowed_ids) + ) + ) + .outerjoin(RepoFork, Repository.fork_id == RepoFork.repo_id) .join(OwnerUser, Repository.user_id == OwnerUser.user_id) + ) if search_q: - like_expression = f'%{safe_str(search_q)}%' - base_q = base_q.filter(or_( - Repository.repo_name.ilike(like_expression), - )) + like_expression = f"%{safe_str(search_q)}%" + base_q = base_q.filter( + or_( + Repository.repo_name.ilike(like_expression), + ) + ) - #TODO: check if we need group_by here ? - #base_q = base_q.group_by(Repository, User) + # TODO: check if we need group_by here ? + # base_q = base_q.group_by(Repository, User) repos_data_total_filtered_count = base_q.count() sort_defined = False - if order_by == 'repo_name': + if order_by == "repo_name": sort_col = func.lower(Repository.repo_name) sort_defined = True - elif order_by == 'user_username': + elif order_by == "user_username": sort_col = OwnerUser.username else: sort_col = getattr(Repository, order_by, None) if sort_defined or sort_col: - if order_dir == 'asc': + if order_dir == "asc": sort_col = sort_col.asc() else: sort_col = sort_col.desc() @@ -145,15 +149,14 @@ class AdminReposView(BaseAppView, DataGridAppView): repos_list = base_q.all() - repos_data = RepoModel().get_repos_as_dict( - repo_list=repos_list, admin=True, super_user_actions=True) + repos_data = RepoModel().get_repos_as_dict(repo_list=repos_list, admin=True, super_user_actions=True) - data = ({ - 'draw': draw, - 'data': repos_data, - 'recordsTotal': repos_data_total_count, - 'recordsFiltered': repos_data_total_filtered_count, - }) + data = { + "draw": draw, + "data": repos_data, + "recordsTotal": repos_data_total_count, + "recordsFiltered": repos_data_total_filtered_count, + } return data @LoginRequired() @@ -162,19 +165,19 @@ class AdminReposView(BaseAppView, DataGridAppView): def repository_new(self): c = self.load_default_context() - new_repo = self.request.GET.get('repo', '') - parent_group_id = safe_int(self.request.GET.get('parent_group')) + new_repo = self.request.GET.get("repo", "") + parent_group_id = safe_int(self.request.GET.get("parent_group")) _gr = RepoGroup.get(parent_group_id) - if not HasPermissionAny('hg.admin', 'hg.create.repository')(): + if not HasPermissionAny("hg.admin", "hg.create.repository")(): # you're not super admin nor have global create permissions, # but maybe you have at least write permission to a parent group ? gr_name = _gr.group_name if _gr else None # create repositories with write permission on group is set to true - create_on_write = HasPermissionAny('hg.create.write_on_repogroup.true')() - group_admin = HasRepoGroupPermissionAny('group.admin')(group_name=gr_name) - group_write = HasRepoGroupPermissionAny('group.write')(group_name=gr_name) + create_on_write = HasPermissionAny("hg.create.write_on_repogroup.true")() + group_admin = HasRepoGroupPermissionAny("group.admin")(group_name=gr_name) + group_write = HasRepoGroupPermissionAny("group.write")(group_name=gr_name) if not (group_admin or (group_write and create_on_write)): raise HTTPForbidden() @@ -184,9 +187,9 @@ class AdminReposView(BaseAppView, DataGridAppView): # apply the defaults from defaults page defaults = SettingsModel().get_default_repo_settings(strip_prefix=True) # set checkbox to autochecked - defaults['repo_copy_permissions'] = True + defaults["repo_copy_permissions"] = True - parent_group_choice = '-1' + parent_group_choice = "-1" if not self._rhodecode_user.is_admin and self._rhodecode_user.personal_repo_group: parent_group_choice = self._rhodecode_user.personal_repo_group @@ -194,16 +197,10 @@ class AdminReposView(BaseAppView, DataGridAppView): if parent_group_id in [x[0] for x in c.repo_groups]: parent_group_choice = safe_str(parent_group_id) - defaults.update({'repo_group': parent_group_choice}) + defaults.update({"repo_group": parent_group_choice}) - data = render('rhodecode:templates/admin/repos/repo_add.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/repos/repo_add.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() @@ -218,36 +215,32 @@ class AdminReposView(BaseAppView, DataGridAppView): try: # CanWriteToGroup validators checks permissions of this POST - form = RepoForm( - self.request.translate, repo_groups=c.repo_groups_choices)() + form = RepoForm(self.request.translate, repo_groups=c.repo_groups_choices)() form_result = form.to_python(dict(self.request.POST)) - copy_permissions = form_result.get('repo_copy_permissions') + copy_permissions = form_result.get("repo_copy_permissions") # create is done sometimes async on celery, db transaction # management is handled there. task = RepoModel().create(form_result, self._rhodecode_user.user_id) task_id = get_task_id(task) except formencode.Invalid as errors: - data = render('rhodecode:templates/admin/repos/repo_add.mako', - self._get_template_context(c), self.request) + data = render("rhodecode:templates/admin/repos/repo_add.mako", self._get_template_context(c), self.request) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception as e: - msg = self._log_creation_exception(e, form_result.get('repo_name')) - h.flash(msg, category='error') - raise HTTPFound(h.route_path('home')) + msg = self._log_creation_exception(e, form_result.get("repo_name")) + h.flash(msg, category="error") + raise HTTPFound(h.route_path("home")) - repo_name = form_result.get('repo_name_full') + repo_name = form_result.get("repo_name_full") PermissionModel().trigger_permission_flush() - raise HTTPFound( - h.route_path('repo_creating', repo_name=repo_name, - _query=dict(task_id=task_id))) + raise HTTPFound(h.route_path("repo_creating", repo_name=repo_name, _query=dict(task_id=task_id))) diff --git a/rhodecode/apps/admin/views/scheduler.py b/rhodecode/apps/admin/views/scheduler.py index bd501ca3..50432b44 100644 --- a/rhodecode/apps/admin/views/scheduler.py +++ b/rhodecode/apps/admin/views/scheduler.py @@ -25,14 +25,13 @@ log = logging.getLogger(__name__) class AdminSchedulerView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def scheduler(self): c = self.load_default_context() - c.active = 'scheduler' + c.active = "scheduler" return self._get_template_context(c) diff --git a/rhodecode/apps/admin/views/security.py b/rhodecode/apps/admin/views/security.py index c15294a6..d2f1a4c7 100644 --- a/rhodecode/apps/admin/views/security.py +++ b/rhodecode/apps/admin/views/security.py @@ -25,22 +25,20 @@ log = logging.getLogger(__name__) class AdminSecurityView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def security(self): c = self.load_default_context() - c.active = 'security' + c.active = "security" return self._get_template_context(c) - @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def admin_security_modify_allowed_vcs_client_versions(self): c = self.load_default_context() - c.active = 'security' + c.active = "security" return self._get_template_context(c) diff --git a/rhodecode/apps/admin/views/sessions.py b/rhodecode/apps/admin/views/sessions.py index e5a83806..41a7b633 100644 --- a/rhodecode/apps/admin/views/sessions.py +++ b/rhodecode/apps/admin/views/sessions.py @@ -23,8 +23,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import BaseAppView from rhodecode.apps._base.navigation import navigation_list -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.lib.utils2 import safe_int from rhodecode.lib import system_info from rhodecode.lib import user_sessions @@ -35,59 +34,53 @@ log = logging.getLogger(__name__) class AdminSessionSettingsView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_sessions(self): c = self.load_default_context() - c.active = 'sessions' + c.active = "sessions" c.navlist = navigation_list(self.request) c.cleanup_older_days = 60 older_than_seconds = 60 * 60 * 24 * c.cleanup_older_days - config = system_info.rhodecode_config().get_value()['value']['config'] - c.session_model = user_sessions.get_session_handler( - config.get('beaker.session.type', 'memory'))(config) + config = system_info.rhodecode_config().get_value()["value"]["config"] + c.session_model = user_sessions.get_session_handler(config.get("beaker.session.type", "memory"))(config) c.session_conf = c.session_model.config c.session_count = c.session_model.get_count() - c.session_expired_count = c.session_model.get_expired_count( - older_than_seconds) + c.session_expired_count = c.session_model.get_expired_count(older_than_seconds) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_sessions_cleanup(self): _ = self.request.translate - expire_days = safe_int(self.request.params.get('expire_days')) + expire_days = safe_int(self.request.params.get("expire_days")) if expire_days is None: expire_days = 60 older_than_seconds = 60 * 60 * 24 * expire_days - config = system_info.rhodecode_config().get_value()['value']['config'] - session_model = user_sessions.get_session_handler( - config.get('beaker.session.type', 'memory'))(config) + config = system_info.rhodecode_config().get_value()["value"]["config"] + session_model = user_sessions.get_session_handler(config.get("beaker.session.type", "memory"))(config) try: - session_model.clean_sessions( - older_than_seconds=older_than_seconds) - h.flash(_('Cleaned up old sessions'), category='success') + session_model.clean_sessions(older_than_seconds=older_than_seconds) + h.flash(_("Cleaned up old sessions"), category="success") except user_sessions.CleanupCommand as msg: - h.flash(str(msg), category='warning') + h.flash(str(msg), category="warning") except Exception as e: - log.exception('Failed session cleanup') - h.flash(_('Failed to cleanup up old sessions'), category='error') + log.exception("Failed session cleanup") + h.flash(_("Failed to cleanup up old sessions"), category="error") - redirect_to = self.request.resource_path( - self.context, route_name='admin_settings_sessions') + redirect_to = self.request.resource_path(self.context, route_name="admin_settings_sessions") return HTTPFound(redirect_to) diff --git a/rhodecode/apps/admin/views/settings.py b/rhodecode/apps/admin/views/settings.py index 7f7c4abc..cf201346 100644 --- a/rhodecode/apps/admin/views/settings.py +++ b/rhodecode/apps/admin/views/settings.py @@ -34,8 +34,7 @@ from rhodecode.apps._base import BaseAppView from rhodecode.apps._base.navigation import navigation_list from rhodecode.apps.svn_support import config_keys from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.lib.celerylib import tasks, run_task from rhodecode.lib.str_utils import safe_str from rhodecode.lib.utils import repo2db_mapper, get_rhodecode_repo_store_path, repo2db_cleanup @@ -43,29 +42,29 @@ from rhodecode.lib.utils2 import str2bool, AttributeDict from rhodecode.lib.index import searcher_from_config from rhodecode.model.db import RhodeCodeUi, Repository -from rhodecode.model.forms import (ApplicationSettingsForm, - ApplicationUiSettingsForm, ApplicationVisualisationForm, - LabsSettingsForm, IssueTrackerPatternsForm) +from rhodecode.model.forms import ( + ApplicationSettingsForm, + ApplicationUiSettingsForm, + ApplicationVisualisationForm, + LabsSettingsForm, + IssueTrackerPatternsForm, +) from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.scm import ScmModel from rhodecode.model.notification import EmailNotificationModel from rhodecode.model.meta import Session -from rhodecode.model.settings import ( - IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound, - SettingsModel) +from rhodecode.model.settings import IssueTrackerSettingsModel, VcsSettingsModel, SettingNotFound, SettingsModel log = logging.getLogger(__name__) class AdminSettingsView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() - c.labs_active = str2bool( - rhodecode.CONFIG.get('labs_settings_active', 'true')) + c.labs_active = str2bool(rhodecode.CONFIG.get("labs_settings_active", "true")) c.navlist = navigation_list(self.request) return c @@ -74,11 +73,11 @@ class AdminSettingsView(BaseAppView): ret = RhodeCodeUi.query().all() if not ret: - raise Exception('Could not get application ui settings !') + raise Exception("Could not get application ui settings !") settings = { # legacy param that needs to be kept - 'web_push_ssl': False, - 'extensions_hgsubversion': False + "web_push_ssl": False, + "extensions_hgsubversion": False, } for each in ret: k = each.ui_key @@ -86,22 +85,22 @@ class AdminSettingsView(BaseAppView): section = each.ui_section # skip some options if they are defined - if f"{section}_{k}" in ['web_push_ssl', 'extensions_hgsubversion']: + if f"{section}_{k}" in ["web_push_ssl", "extensions_hgsubversion"]: continue - if k == '/': - k = 'root_path' + if k == "/": + k = "root_path" - if k in ['publish', 'enabled']: + if k in ["publish", "enabled"]: v = str2bool(v) - if k.find('.') != -1: - k = k.replace('.', '_') + if k.find(".") != -1: + k = k.replace(".", "_") - if each.ui_section in ['hooks', 'extensions']: + if each.ui_section in ["hooks", "extensions"]: v = each.ui_active - settings[section + '_' + k] = v + settings[section + "_" + k] = v return settings @@ -110,17 +109,19 @@ class AdminSettingsView(BaseAppView): defaults = SettingsModel().get_all_settings() defaults.update(cls._get_ui_settings()) - defaults.update({ - 'new_svn_branch': '', - 'new_svn_tag': '', - }) + defaults.update( + { + "new_svn_branch": "", + "new_svn_tag": "", + } + ) return defaults @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_vcs(self): c = self.load_default_context() - c.active = 'vcs' + c.active = "vcs" model = VcsSettingsModel() c.svn_branch_patterns = model.get_global_svn_branch_patterns() c.svn_tag_patterns = model.get_global_svn_tag_patterns() @@ -128,23 +129,17 @@ class AdminSettingsView(BaseAppView): c.svn_config_path = rhodecode.ConfigGet().get_str(config_keys.config_file_path) defaults = self._form_defaults() - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_vcs_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'vcs' + c.active = "vcs" model = VcsSettingsModel() c.svn_branch_patterns = model.get_global_svn_branch_patterns() @@ -157,18 +152,17 @@ class AdminSettingsView(BaseAppView): try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: - h.flash( - _("Some form inputs contain invalid data."), - category='error') - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) + h.flash(_("Some form inputs contain invalid data."), category="error") + data = render( + "rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) @@ -181,67 +175,53 @@ class AdminSettingsView(BaseAppView): model.create_or_update_global_pr_settings(form_result) except Exception: log.exception("Exception while updating settings") - h.flash(_('Error occurred during updating ' - 'application settings'), category='error') + h.flash(_("Error occurred during updating application settings"), category="error") else: Session().commit() - h.flash(_('Updated VCS settings'), category='success') - raise HTTPFound(h.route_path('admin_settings_vcs')) + h.flash(_("Updated VCS settings"), category="success") + raise HTTPFound(h.route_path("admin_settings_vcs")) - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_vcs_delete_svn_pattern(self): - delete_pattern_id = self.request.POST.get('delete_svn_pattern') + delete_pattern_id = self.request.POST.get("delete_svn_pattern") model = VcsSettingsModel() try: model.delete_global_svn_pattern(delete_pattern_id) except SettingNotFound: - log.exception( - 'Failed to delete svn_pattern with id %s', delete_pattern_id) + log.exception("Failed to delete svn_pattern with id %s", delete_pattern_id) raise HTTPNotFound() Session().commit() return True @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_mapping(self): c = self.load_default_context() - c.active = 'mapping' + c.active = "mapping" c.storage_path = get_rhodecode_repo_store_path() - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_mapping_create(self): _ = self.request.translate c = self.load_default_context() - c.active = 'mapping' - invalidate_cache = self.request.POST.get('invalidate', False) - log.debug('rescanning repo location') + c.active = "mapping" + invalidate_cache = self.request.POST.get("invalidate", False) + log.debug("rescanning repo location") if invalidate_cache: - log.debug('invalidating all repositories cache') + log.debug("invalidating all repositories cache") for repo in Repository.get_all(): ScmModel().mark_for_invalidation(repo.repo_name, delete=True) @@ -250,227 +230,216 @@ class AdminSettingsView(BaseAppView): PermissionModel().trigger_permission_flush() def _repr(rm_repo): - return ', '.join(map(safe_str, rm_repo)) or '-' + return ", ".join(map(safe_str, rm_repo)) or "-" if errors: - h.flash(_('Errors during scan: {}').format(_repr(errors), ), category='error') + h.flash( + _("Errors during scan: {}").format( + _repr(errors), + ), + category="error", + ) - h.flash(_('Repositories successfully scanned: Added: {}').format(_repr(added)), category='success') - raise HTTPFound(h.route_path('admin_settings_mapping')) + h.flash(_("Repositories successfully scanned: Added: {}").format(_repr(added)), category="success") + raise HTTPFound(h.route_path("admin_settings_mapping")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_mapping_cleanup(self): _ = self.request.translate c = self.load_default_context() - c.active = 'mapping' - log.debug('rescanning repo location') + c.active = "mapping" + log.debug("rescanning repo location") removed, errors = repo2db_cleanup() PermissionModel().trigger_permission_flush() def _repr(rm_repo): - return ', '.join(map(safe_str, rm_repo)) or '-' + return ", ".join(map(safe_str, rm_repo)) or "-" - h.flash(_('Repositories successfully scanned: Errors: {}, Added: {}').format(errors, _repr(removed)), category='success') - raise HTTPFound(h.route_path('admin_settings_mapping')) + h.flash( + _("Repositories successfully scanned: Errors: {}, Added: {}").format(errors, _repr(removed)), + category="success", + ) + raise HTTPFound(h.route_path("admin_settings_mapping")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_global(self): c = self.load_default_context() - c.active = 'global' - c.personal_repo_group_default_pattern = RepoGroupModel()\ - .get_personal_group_name_pattern() + c.active = "global" + c.personal_repo_group_default_pattern = RepoGroupModel().get_personal_group_name_pattern() - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_global_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'global' - c.personal_repo_group_default_pattern = RepoGroupModel()\ - .get_personal_group_name_pattern() + c.active = "global" + c.personal_repo_group_default_pattern = RepoGroupModel().get_personal_group_name_pattern() application_form = ApplicationSettingsForm(self.request.translate)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: - h.flash( - _("Some form inputs contain invalid data."), - category='error') - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) + h.flash(_("Some form inputs contain invalid data."), category="error") + data = render( + "rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) settings = [ - ('title', 'rhodecode_title', 'unicode'), - ('realm', 'rhodecode_realm', 'unicode'), - ('pre_code', 'rhodecode_pre_code', 'unicode'), - ('post_code', 'rhodecode_post_code', 'unicode'), - ('captcha_public_key', 'rhodecode_captcha_public_key', 'unicode'), - ('captcha_private_key', 'rhodecode_captcha_private_key', 'unicode'), - ('create_personal_repo_group', 'rhodecode_create_personal_repo_group', 'bool'), - ('personal_repo_group_pattern', 'rhodecode_personal_repo_group_pattern', 'unicode'), + ("title", "rhodecode_title", "unicode"), + ("realm", "rhodecode_realm", "unicode"), + ("pre_code", "rhodecode_pre_code", "unicode"), + ("post_code", "rhodecode_post_code", "unicode"), + ("captcha_public_key", "rhodecode_captcha_public_key", "unicode"), + ("captcha_private_key", "rhodecode_captcha_private_key", "unicode"), + ("create_personal_repo_group", "rhodecode_create_personal_repo_group", "bool"), + ("personal_repo_group_pattern", "rhodecode_personal_repo_group_pattern", "unicode"), ] try: for setting, form_key, type_ in settings: - sett = SettingsModel().create_or_update_setting( - setting, form_result[form_key], type_) + sett = SettingsModel().create_or_update_setting(setting, form_result[form_key], type_) Session().add(sett) Session().commit() SettingsModel().invalidate_settings_cache() - h.flash(_('Updated application settings'), category='success') + h.flash(_("Updated application settings"), category="success") except Exception: log.exception("Exception while updating application settings") - h.flash( - _('Error occurred during updating application settings'), - category='error') + h.flash(_("Error occurred during updating application settings"), category="error") - raise HTTPFound(h.route_path('admin_settings_global')) + raise HTTPFound(h.route_path("admin_settings_global")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_visual(self): c = self.load_default_context() - c.active = 'visual' + c.active = "visual" - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_visual_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'visual' + c.active = "visual" application_form = ApplicationVisualisationForm(self.request.translate)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: - h.flash( - _("Some form inputs contain invalid data."), - category='error') - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) + h.flash(_("Some form inputs contain invalid data."), category="error") + data = render( + "rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) try: settings = [ - ('show_public_icon', 'rhodecode_show_public_icon', 'bool'), - ('show_private_icon', 'rhodecode_show_private_icon', 'bool'), - ('stylify_metatags', 'rhodecode_stylify_metatags', 'bool'), - ('repository_fields', 'rhodecode_repository_fields', 'bool'), - ('dashboard_items', 'rhodecode_dashboard_items', 'int'), - ('admin_grid_items', 'rhodecode_admin_grid_items', 'int'), - ('show_version', 'rhodecode_show_version', 'bool'), - ('use_gravatar', 'rhodecode_use_gravatar', 'bool'), - ('markup_renderer', 'rhodecode_markup_renderer', 'unicode'), - ('gravatar_url', 'rhodecode_gravatar_url', 'unicode'), - ('clone_uri_tmpl', 'rhodecode_clone_uri_tmpl', 'unicode'), - ('clone_uri_id_tmpl', 'rhodecode_clone_uri_id_tmpl', 'unicode'), - ('clone_uri_ssh_tmpl', 'rhodecode_clone_uri_ssh_tmpl', 'unicode'), - ('support_url', 'rhodecode_support_url', 'unicode'), - ('show_revision_number', 'rhodecode_show_revision_number', 'bool'), - ('show_sha_length', 'rhodecode_show_sha_length', 'int'), + ("show_public_icon", "rhodecode_show_public_icon", "bool"), + ("show_private_icon", "rhodecode_show_private_icon", "bool"), + ("stylify_metatags", "rhodecode_stylify_metatags", "bool"), + ("repository_fields", "rhodecode_repository_fields", "bool"), + ("dashboard_items", "rhodecode_dashboard_items", "int"), + ("admin_grid_items", "rhodecode_admin_grid_items", "int"), + ("show_version", "rhodecode_show_version", "bool"), + ("use_gravatar", "rhodecode_use_gravatar", "bool"), + ("markup_renderer", "rhodecode_markup_renderer", "unicode"), + ("gravatar_url", "rhodecode_gravatar_url", "unicode"), + ("clone_uri_tmpl", "rhodecode_clone_uri_tmpl", "unicode"), + ("clone_uri_id_tmpl", "rhodecode_clone_uri_id_tmpl", "unicode"), + ("clone_uri_ssh_tmpl", "rhodecode_clone_uri_ssh_tmpl", "unicode"), + ("support_url", "rhodecode_support_url", "unicode"), + ("show_revision_number", "rhodecode_show_revision_number", "bool"), + ("show_sha_length", "rhodecode_show_sha_length", "int"), ] for setting, form_key, type_ in settings: - sett = SettingsModel().create_or_update_setting( - setting, form_result[form_key], type_) + sett = SettingsModel().create_or_update_setting(setting, form_result[form_key], type_) Session().add(sett) Session().commit() SettingsModel().invalidate_settings_cache() - h.flash(_('Updated visualisation settings'), category='success') + h.flash(_("Updated visualisation settings"), category="success") except Exception: log.exception("Exception updating visualization settings") - h.flash(_('Error occurred during updating ' - 'visualisation settings'), - category='error') + h.flash(_("Error occurred during updating visualisation settings"), category="error") - raise HTTPFound(h.route_path('admin_settings_visual')) + raise HTTPFound(h.route_path("admin_settings_visual")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_issuetracker(self): c = self.load_default_context() - c.active = 'issuetracker' + c.active = "issuetracker" defaults = c.rc_config - entry_key = 'rhodecode_issuetracker_pat_' + entry_key = "rhodecode_issuetracker_pat_" c.issuetracker_entries = {} for k, v in defaults.items(): if k.startswith(entry_key): - uid = k[len(entry_key):] + uid = k[len(entry_key) :] c.issuetracker_entries[uid] = None for uid in c.issuetracker_entries: - c.issuetracker_entries[uid] = AttributeDict({ - 'pat': defaults.get('rhodecode_issuetracker_pat_' + uid), - 'url': defaults.get('rhodecode_issuetracker_url_' + uid), - 'pref': defaults.get('rhodecode_issuetracker_pref_' + uid), - 'desc': defaults.get('rhodecode_issuetracker_desc_' + uid), - }) + c.issuetracker_entries[uid] = AttributeDict( + { + "pat": defaults.get("rhodecode_issuetracker_pat_" + uid), + "url": defaults.get("rhodecode_issuetracker_url_" + uid), + "pref": defaults.get("rhodecode_issuetracker_pref_" + uid), + "desc": defaults.get("rhodecode_issuetracker_desc_" + uid), + } + ) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_issuetracker_test(self): error_container = [] urlified_commit = h.urlify_commit_message( - self.request.POST.get('test_text', ''), - 'repo_group/test_repo1', error_container=error_container) + self.request.POST.get("test_text", ""), "repo_group/test_repo1", error_container=error_container + ) if error_container: + def converter(inp): return h.html_escape(inp) - return 'ERRORS: ' + '\n'.join(map(converter, error_container)) + return "ERRORS: " + "\n".join(map(converter, error_container)) return urlified_commit @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_issuetracker_update(self): _ = self.request.translate @@ -481,132 +450,115 @@ class AdminSettingsView(BaseAppView): form = IssueTrackerPatternsForm(self.request.translate)() data = form.to_python(self.request.POST) except formencode.Invalid as errors: - log.exception('Failed to add new pattern') + log.exception("Failed to add new pattern") error = errors - h.flash(_(f'Invalid issue tracker pattern: {error}'), - category='error') - raise HTTPFound(h.route_path('admin_settings_issuetracker')) + h.flash(_(f"Invalid issue tracker pattern: {error}"), category="error") + raise HTTPFound(h.route_path("admin_settings_issuetracker")) if data: - for uid in data.get('delete_patterns', []): + for uid in data.get("delete_patterns", []): settings_model.delete_entries(uid) - for pattern in data.get('patterns', []): + for pattern in data.get("patterns", []): for setting, value, type_ in pattern: - sett = settings_model.create_or_update_setting( - setting, value, type_) + sett = settings_model.create_or_update_setting(setting, value, type_) Session().add(sett) Session().commit() SettingsModel().invalidate_settings_cache() - h.flash(_('Updated issue tracker entries'), category='success') - raise HTTPFound(h.route_path('admin_settings_issuetracker')) + h.flash(_("Updated issue tracker entries"), category="success") + raise HTTPFound(h.route_path("admin_settings_issuetracker")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_issuetracker_delete(self): _ = self.request.translate self.load_default_context() - uid = self.request.POST.get('uid') + uid = self.request.POST.get("uid") try: IssueTrackerSettingsModel().delete_entries(uid) except Exception: - log.exception('Failed to delete issue tracker setting %s', uid) + log.exception("Failed to delete issue tracker setting %s", uid) raise HTTPNotFound() SettingsModel().invalidate_settings_cache() - h.flash(_('Removed issue tracker entry.'), category='success') + h.flash(_("Removed issue tracker entry."), category="success") - return {'deleted': uid} + return {"deleted": uid} @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_email(self): c = self.load_default_context() - c.active = 'email' + c.active = "email" c.rhodecode_ini = rhodecode.CONFIG - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_email_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'email' + c.active = "email" - test_email = self.request.POST.get('test_email') + test_email = self.request.POST.get("test_email") if not test_email: - h.flash(_('Please enter email address'), category='error') - raise HTTPFound(h.route_path('admin_settings_email')) + h.flash(_("Please enter email address"), category="error") + raise HTTPFound(h.route_path("admin_settings_email")) - email_kwargs = { - 'date': datetime.datetime.now(), - 'user': self._rhodecode_db_user - } + email_kwargs = {"date": datetime.datetime.now(), "user": self._rhodecode_db_user} (subject, email_body, email_body_plaintext) = EmailNotificationModel().render_email( - EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs) + EmailNotificationModel.TYPE_EMAIL_TEST, **email_kwargs + ) recipients = [test_email] if test_email else None - run_task(tasks.send_email, recipients, subject, - email_body_plaintext, email_body) + run_task(tasks.send_email, recipients, subject, email_body_plaintext, email_body) - h.flash(_('Send email task created'), category='success') - raise HTTPFound(h.route_path('admin_settings_email')) + h.flash(_("Send email task created"), category="success") + raise HTTPFound(h.route_path("admin_settings_email")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_hooks(self): c = self.load_default_context() - c.active = 'hooks' + c.active = "hooks" model = SettingsModel() c.hooks = model.get_builtin_hooks() c.custom_hooks = model.get_custom_hooks() - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_hooks_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'hooks' + c.active = "hooks" if c.visual.allow_custom_hooks_settings: - ui_key = self.request.POST.get('new_hook_ui_key') - ui_value = self.request.POST.get('new_hook_ui_value') + ui_key = self.request.POST.get("new_hook_ui_key") + ui_value = self.request.POST.get("new_hook_ui_value") - hook_id = self.request.POST.get('hook_id') + hook_id = self.request.POST.get("hook_id") new_hook = False model = SettingsModel() try: if ui_value and ui_key: model.create_or_update_hook(ui_key, ui_value) - h.flash(_('Added new hook'), category='success') + h.flash(_("Added new hook"), category="success") new_hook = True elif hook_id: RhodeCodeUi.delete(hook_id) @@ -615,26 +567,24 @@ class AdminSettingsView(BaseAppView): # check for edits update = False _d = self.request.POST.dict_of_lists() - for k, v in zip(_d.get('hook_ui_key', []), - _d.get('hook_ui_value_new', [])): + for k, v in zip(_d.get("hook_ui_key", []), _d.get("hook_ui_value_new", [])): model.create_or_update_hook(k, v) update = True if update and not new_hook: - h.flash(_('Updated hooks'), category='success') + h.flash(_("Updated hooks"), category="success") Session().commit() except Exception: log.exception("Exception during hook creation") - h.flash(_('Error occurred during hook creation'), - category='error') + h.flash(_("Error occurred during hook creation"), category="error") - raise HTTPFound(h.route_path('admin_settings_hooks')) + raise HTTPFound(h.route_path("admin_settings_hooks")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_search(self): c = self.load_default_context() - c.active = 'search' + c.active = "search" c.searcher = searcher_from_config(self.request.registry.settings) c.statistics = c.searcher.statistics(self.request.translate) @@ -642,78 +592,63 @@ class AdminSettingsView(BaseAppView): return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_labs(self): c = self.load_default_context() if not c.labs_active: - raise HTTPFound(h.route_path('admin_settings')) + raise HTTPFound(h.route_path("admin_settings")) - c.active = 'labs' + c.active = "labs" c.lab_settings = _LAB_SETTINGS - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_labs_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'labs' + c.active = "labs" application_form = LabsSettingsForm(self.request.translate)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: - h.flash( - _("Some form inputs contain invalid data."), - category='error') - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) + h.flash(_("Some form inputs contain invalid data."), category="error") + data = render( + "rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) try: session = Session() for setting in _LAB_SETTINGS: - setting_name = setting.key[len('rhodecode_'):] - sett = SettingsModel().create_or_update_setting( - setting_name, form_result[setting.key], setting.type) + setting_name = setting.key[len("rhodecode_") :] + sett = SettingsModel().create_or_update_setting(setting_name, form_result[setting.key], setting.type) session.add(sett) except Exception: - log.exception('Exception while updating lab settings') - h.flash(_('Error occurred during updating labs settings'), - category='error') + log.exception("Exception while updating lab settings") + h.flash(_("Error occurred during updating labs settings"), category="error") else: Session().commit() SettingsModel().invalidate_settings_cache() - h.flash(_('Updated Labs settings'), category='success') - raise HTTPFound(h.route_path('admin_settings_labs')) + h.flash(_("Updated Labs settings"), category="success") + raise HTTPFound(h.route_path("admin_settings_labs")) - data = render('rhodecode:templates/admin/settings/settings.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=self._form_defaults(), - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/settings/settings.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=self._form_defaults(), encoding="UTF-8", force_defaults=False) return Response(html) @@ -722,12 +657,9 @@ class AdminSettingsView(BaseAppView): # :param group: the i18ned group in which we should dispaly this setting # :param label: the i18ned label we should display for this setting # :param help: the i18ned help we should dispaly for this setting -LabSetting = collections.namedtuple( - 'LabSetting', ('key', 'type', 'group', 'label', 'help')) +LabSetting = collections.namedtuple("LabSetting", ("key", "type", "group", "label", "help")) # This list has to be kept in sync with the form # rhodecode.model.forms.LabsSettingsForm. -_LAB_SETTINGS = [ - -] +_LAB_SETTINGS = [] diff --git a/rhodecode/apps/admin/views/svn_config.py b/rhodecode/apps/admin/views/svn_config.py index 102d8d4f..2d6ebba2 100644 --- a/rhodecode/apps/admin/views/svn_config.py +++ b/rhodecode/apps/admin/views/svn_config.py @@ -19,36 +19,31 @@ import logging - from rhodecode.apps._base import BaseAppView from rhodecode.apps.svn_support.utils import generate_mod_dav_svn_config -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired log = logging.getLogger(__name__) class AdminSvnConfigView(BaseAppView): - @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def vcs_svn_generate_config(self): _ = self.request.translate try: file_path = generate_mod_dav_svn_config(self.request.registry) msg = { - 'message': _('Apache configuration for Subversion generated at `{}`.').format(file_path), - 'level': 'success', + "message": _("Apache configuration for Subversion generated at `{}`.").format(file_path), + "level": "success", } except Exception: - log.exception( - 'Exception while generating the Apache ' - 'configuration for Subversion.') + log.exception("Exception while generating the Apache configuration for Subversion.") msg = { - 'message': _('Failed to generate the Apache configuration for Subversion.'), - 'level': 'error', + "message": _("Failed to generate the Apache configuration for Subversion."), + "level": "error", } - data = {'message': msg} + data = {"message": msg} return data diff --git a/rhodecode/apps/admin/views/system_info.py b/rhodecode/apps/admin/views/system_info.py index 9a798274..ce75a584 100644 --- a/rhodecode/apps/admin/views/system_info.py +++ b/rhodecode/apps/admin/views/system_info.py @@ -26,7 +26,7 @@ import rhodecode from rhodecode.apps._base import BaseAppView from rhodecode.apps._base.navigation import navigation_list from rhodecode.lib import helpers as h -from rhodecode.lib.auth import (LoginRequired, HasPermissionAllDecorator) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator from rhodecode.lib.utils2 import str2bool from rhodecode.lib import system_info from rhodecode.model.update import UpdateModel @@ -41,51 +41,49 @@ class AdminSystemInfoSettingsView(BaseAppView): def get_env_data(self): black_list = [ - 'NIX_LDFLAGS', - 'NIX_CFLAGS_COMPILE', - 'propagatedBuildInputs', - 'propagatedNativeBuildInputs', - 'postInstall', - 'buildInputs', - 'buildPhase', - 'preShellHook', - 'preShellHook', - 'preCheck', - 'preBuild', - 'postShellHook', - 'postFixup', - 'postCheck', - 'nativeBuildInputs', - 'installPhase', - 'installCheckPhase', - 'checkPhase', - 'configurePhase', - 'shellHook' - ] - secret_list = [ - 'RHODECODE_USER_PASS' + "NIX_LDFLAGS", + "NIX_CFLAGS_COMPILE", + "propagatedBuildInputs", + "propagatedNativeBuildInputs", + "postInstall", + "buildInputs", + "buildPhase", + "preShellHook", + "preShellHook", + "preCheck", + "preBuild", + "postShellHook", + "postFixup", + "postCheck", + "nativeBuildInputs", + "installPhase", + "installCheckPhase", + "checkPhase", + "configurePhase", + "shellHook", ] + secret_list = ["RHODECODE_USER_PASS"] for k, v in sorted(os.environ.items()): if k in black_list: continue if k in secret_list: - v = '*****' + v = "*****" yield k, v @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_system_info(self): _ = self.request.translate c = self.load_default_context() - c.active = 'system' + c.active = "system" c.navlist = navigation_list(self.request) # TODO(marcink), figure out how to allow only selected users to do this c.allowed_to_snapshot = self._rhodecode_user.admin - snapshot = str2bool(self.request.params.get('snapshot')) + snapshot = str2bool(self.request.params.get("snapshot")) c.rhodecode_update_url = UpdateModel().get_update_url() c.env_data = self.get_env_data() @@ -94,127 +92,122 @@ class AdminSystemInfoSettingsView(BaseAppView): for key, val in server_info.items(): setattr(c, key, val) - def val(name, subkey='human_value'): + def val(name, subkey="human_value"): return server_info[name][subkey] def state(name): - return server_info[name]['state'] + return server_info[name]["state"] def val2(name): - val = server_info[name]['human_value'] - state = server_info[name]['state'] + val = server_info[name]["human_value"] + state = server_info[name]["state"] return val, state - update_info_msg = _('Note: please make sure this server can ' - 'access `${url}` for the update link to work', - mapping=dict(url=c.rhodecode_update_url)) + update_info_msg = _( + "Note: please make sure this server can access `${url}` for the update link to work", + mapping=dict(url=c.rhodecode_update_url), + ) version = UpdateModel().get_stored_version() - is_outdated = UpdateModel().is_outdated( - rhodecode.__version__, version) - update_state = { - 'type': 'warning', - 'message': 'New version available: {}'.format(version) - } \ - if is_outdated else {} + is_outdated = UpdateModel().is_outdated(rhodecode.__version__, version) + update_state = ( + {"type": "warning", "message": "New version available: {}".format(version)} if is_outdated else {} + ) c.data_items = [ # update info - (_('Update info'), h.literal( - '%s.' % ( - _('Check for updates')) + - '
%s.' % (update_info_msg) - ), ''), - + ( + _("Update info"), + h.literal( + '%s.' % (_("Check for updates")) + + "
%s." % (update_info_msg) + ), + "", + ), # RhodeCode specific - (_('RhodeCode Version'), val('rhodecode_app')['text'], state('rhodecode_app')), - (_('Latest version'), version, update_state), - (_('RhodeCode Base URL'), val('rhodecode_config')['config'].get('app.base_url'), state('rhodecode_config')), - (_('RhodeCode Server IP'), val('server')['server_ip'], state('server')), - (_('RhodeCode Server ID'), val('server')['server_id'], state('server')), - (_('RhodeCode Configuration'), val('rhodecode_config')['path'], state('rhodecode_config')), - (_('RhodeCode Certificate'), val('rhodecode_config')['cert_path'], state('rhodecode_config')), - (_('Workers'), val('rhodecode_config')['config']['server:main'].get('workers', '?'), state('rhodecode_config')), - (_('Worker Type'), val('rhodecode_config')['config']['server:main'].get('worker_class', 'sync'), state('rhodecode_config')), - ('', '', ''), # spacer - + (_("RhodeCode Version"), val("rhodecode_app")["text"], state("rhodecode_app")), + (_("Latest version"), version, update_state), + (_("RhodeCode Base URL"), val("rhodecode_config")["config"].get("app.base_url"), state("rhodecode_config")), + (_("RhodeCode Server IP"), val("server")["server_ip"], state("server")), + (_("RhodeCode Server ID"), val("server")["server_id"], state("server")), + (_("RhodeCode Configuration"), val("rhodecode_config")["path"], state("rhodecode_config")), + (_("RhodeCode Certificate"), val("rhodecode_config")["cert_path"], state("rhodecode_config")), + ( + _("Workers"), + val("rhodecode_config")["config"]["server:main"].get("workers", "?"), + state("rhodecode_config"), + ), + ( + _("Worker Type"), + val("rhodecode_config")["config"]["server:main"].get("worker_class", "sync"), + state("rhodecode_config"), + ), + ("", "", ""), # spacer # Database - (_('Database'), val('database')['url'], state('database')), - (_('Database version'), val('database')['version'], state('database')), - ('', '', ''), # spacer - + (_("Database"), val("database")["url"], state("database")), + (_("Database version"), val("database")["version"], state("database")), + ("", "", ""), # spacer # Platform/Python - (_('Platform'), val('platform')['name'], state('platform')), - (_('Platform UUID'), val('platform')['uuid'], state('platform')), - (_('Lang'), val('locale'), state('locale')), - (_('Python version'), val('python')['version'], state('python')), - (_('Python path'), val('python')['executable'], state('python')), - ('', '', ''), # spacer - + (_("Platform"), val("platform")["name"], state("platform")), + (_("Platform UUID"), val("platform")["uuid"], state("platform")), + (_("Lang"), val("locale"), state("locale")), + (_("Python version"), val("python")["version"], state("python")), + (_("Python path"), val("python")["executable"], state("python")), + ("", "", ""), # spacer # Systems stats - (_('CPU'), val('cpu')['text'], state('cpu')), - (_('Load'), val('load')['text'], state('load')), - (_('Memory'), val('memory')['text'], state('memory')), - (_('Uptime'), val('uptime')['text'], state('uptime')), - ('', '', ''), # spacer - + (_("CPU"), val("cpu")["text"], state("cpu")), + (_("Load"), val("load")["text"], state("load")), + (_("Memory"), val("memory")["text"], state("memory")), + (_("Uptime"), val("uptime")["text"], state("uptime")), + ("", "", ""), # spacer # ulimit - (_('Ulimit'), val('ulimit')['text'], state('ulimit')), - + (_("Ulimit"), val("ulimit")["text"], state("ulimit")), # Repo storage - (_('Storage location'), val('storage')['path'], state('storage')), - (_('Storage info'), val('storage')['text'], state('storage')), - (_('Storage inodes'), val('storage_inodes')['text'], state('storage_inodes')), - ('', '', ''), # spacer - - (_('Gist storage location'), val('storage_gist')['path'], state('storage_gist')), - (_('Gist storage info'), val('storage_gist')['text'], state('storage_gist')), - ('', '', ''), # spacer - - (_('Artifacts storage backend'), val('storage_artifacts')['type'], state('storage_artifacts')), - (_('Artifacts storage location'), val('storage_artifacts')['path'], state('storage_artifacts')), - (_('Artifacts info'), val('storage_artifacts')['text'], state('storage_artifacts')), - ('', '', ''), # spacer - - (_('Archive cache storage backend'), val('storage_archive')['type'], state('storage_archive')), - (_('Archive cache storage location'), val('storage_archive')['path'], state('storage_archive')), - (_('Archive cache info'), val('storage_archive')['text'], state('storage_archive')), - ('', '', ''), # spacer - - - (_('Temp storage location'), val('storage_temp')['path'], state('storage_temp')), - (_('Temp storage info'), val('storage_temp')['text'], state('storage_temp')), - ('', '', ''), # spacer - - (_('Search info'), val('search')['text'], state('search')), - (_('Search location'), val('search')['location'], state('search')), - ('', '', ''), # spacer - + (_("Storage location"), val("storage")["path"], state("storage")), + (_("Storage info"), val("storage")["text"], state("storage")), + (_("Storage inodes"), val("storage_inodes")["text"], state("storage_inodes")), + ("", "", ""), # spacer + (_("Gist storage location"), val("storage_gist")["path"], state("storage_gist")), + (_("Gist storage info"), val("storage_gist")["text"], state("storage_gist")), + ("", "", ""), # spacer + (_("Artifacts storage backend"), val("storage_artifacts")["type"], state("storage_artifacts")), + (_("Artifacts storage location"), val("storage_artifacts")["path"], state("storage_artifacts")), + (_("Artifacts info"), val("storage_artifacts")["text"], state("storage_artifacts")), + ("", "", ""), # spacer + (_("Archive cache storage backend"), val("storage_archive")["type"], state("storage_archive")), + (_("Archive cache storage location"), val("storage_archive")["path"], state("storage_archive")), + (_("Archive cache info"), val("storage_archive")["text"], state("storage_archive")), + ("", "", ""), # spacer + (_("Temp storage location"), val("storage_temp")["path"], state("storage_temp")), + (_("Temp storage info"), val("storage_temp")["text"], state("storage_temp")), + ("", "", ""), # spacer + (_("Search info"), val("search")["text"], state("search")), + (_("Search location"), val("search")["location"], state("search")), + ("", "", ""), # spacer # VCS specific - (_('VCS Backends'), val('vcs_backends'), state('vcs_backends')), - (_('VCS Server'), val('vcs_server')['text'], state('vcs_server')), - (_('GIT'), val('git'), state('git')), - (_('HG'), val('hg'), state('hg')), - (_('SVN'), val('svn'), state('svn')), - + (_("VCS Backends"), val("vcs_backends"), state("vcs_backends")), + (_("VCS Server"), val("vcs_server")["text"], state("vcs_server")), + (_("GIT"), val("git"), state("git")), + (_("HG"), val("hg"), state("hg")), + (_("SVN"), val("svn"), state("svn")), ] c.rhodecode_data_items = [ - (k, v) for k, v in sorted((val('rhodecode_server_config') or {}).items(), key=lambda x: x[0].lower()) + (k, v) for k, v in sorted((val("rhodecode_server_config") or {}).items(), key=lambda x: x[0].lower()) ] c.vcsserver_data_items = [ - (k, v) for k, v in sorted((val('vcs_server_config') or {}).items(), key=lambda x: x[0].lower()) + (k, v) for k, v in sorted((val("vcs_server_config") or {}).items(), key=lambda x: x[0].lower()) ] if snapshot: if c.allowed_to_snapshot: c.data_items.pop(0) # remove server info - self.request.override_renderer = 'admin/settings/settings_system_snapshot.mako' + self.request.override_renderer = "admin/settings/settings_system_snapshot.mako" else: - h.flash('You are not allowed to do this', category='warning') + h.flash("You are not allowed to do this", category="warning") return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_system_info_check_update(self): _ = self.request.translate c = self.load_default_context() @@ -228,24 +221,24 @@ class AdminSystemInfoSettingsView(BaseAppView): data = UpdateModel().get_update_data(update_url) except urllib.error.URLError as e: log.exception("Exception contacting upgrade server") - self.request.override_renderer = 'string' - return _err('Failed to contact upgrade server: %r' % e) + self.request.override_renderer = "string" + return _err("Failed to contact upgrade server: %r" % e) except ValueError as e: log.exception("Bad data sent from update server") - self.request.override_renderer = 'string' - return _err('Bad data sent from update server') + self.request.override_renderer = "string" + return _err("Bad data sent from update server") - latest = data['versions'][0] + latest = data["versions"][0] c.update_url = update_url c.latest_data = latest - c.latest_ver = (latest['version'] or '').strip() - c.cur_ver = self.request.GET.get('ver') or rhodecode.__version__ + c.latest_ver = (latest["version"] or "").strip() + c.cur_ver = self.request.GET.get("ver") or rhodecode.__version__ c.should_upgrade = False is_outdated = UpdateModel().is_outdated(c.cur_ver, c.latest_ver) if is_outdated: c.should_upgrade = True - c.important_notices = latest['general'] - UpdateModel().store_version(latest['version']) + c.important_notices = latest["general"] + UpdateModel().store_version(latest["version"]) return self._get_template_context(c) diff --git a/rhodecode/apps/admin/views/user_groups.py b/rhodecode/apps/admin/views/user_groups.py index b2b28980..cdfb8899 100644 --- a/rhodecode/apps/admin/views/user_groups.py +++ b/rhodecode/apps/admin/views/user_groups.py @@ -28,15 +28,13 @@ from pyramid.renderers import render from rhodecode import events from rhodecode.apps._base import BaseAppView, DataGridAppView -from rhodecode.lib.auth import ( - LoginRequired, NotAnonymous, CSRFRequired, HasPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, NotAnonymous, CSRFRequired, HasPermissionAnyDecorator from rhodecode.lib import helpers as h, audit_logger from rhodecode.lib.str_utils import safe_str from rhodecode.model.forms import UserGroupForm from rhodecode.model.permission import PermissionModel -from rhodecode.model.db import ( - or_, count, User, UserGroup, UserGroupMember, in_filter_generator) +from rhodecode.model.db import or_, count, User, UserGroup, UserGroupMember, in_filter_generator from rhodecode.model.meta import Session from rhodecode.model.user_group import UserGroupModel from rhodecode.model.db import true @@ -45,11 +43,9 @@ log = logging.getLogger(__name__) class AdminUserGroupsView(BaseAppView, DataGridAppView): - def load_default_context(self): c = self._get_local_tmpl_context() - PermissionModel().set_global_permission_choices( - c, gettext_translator=self.request.translate) + PermissionModel().set_global_permission_choices(c, gettext_translator=self.request.translate) return c # permission check in data loading of @@ -66,18 +62,16 @@ class AdminUserGroupsView(BaseAppView, DataGridAppView): def user_groups_list_data(self): self.load_default_context() column_map = { - 'active': 'users_group_active', - 'description': 'user_group_description', - 'members': 'members_total', - 'owner': 'user_username', - 'sync': 'group_data' + "active": "users_group_active", + "description": "user_group_description", + "members": "members_total", + "owner": "user_username", + "sync": "group_data", } draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) - _render = self.request.get_partial_renderer( - 'rhodecode:templates/data_table/_dt_elements.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/data_table/_dt_elements.mako") def user_group_name(user_group_name): return _render("user_group_name", user_group_name) @@ -86,66 +80,81 @@ class AdminUserGroupsView(BaseAppView, DataGridAppView): return _render("user_group_actions", user_group_id, user_group_name) def user_profile(username): - return _render('user_profile', username) + return _render("user_profile", username) - _perms = ['usergroup.admin'] + _perms = ["usergroup.admin"] allowed_ids = [-1] + self._rhodecode_user.user_group_acl_ids_from_stack(_perms) - user_groups_data_total_count = UserGroup.query()\ - .filter(or_( - # generate multiple IN to fix limitation problems - *in_filter_generator(UserGroup.users_group_id, allowed_ids) - ))\ + user_groups_data_total_count = ( + UserGroup.query() + .filter( + or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(UserGroup.users_group_id, allowed_ids) + ) + ) .count() + ) - user_groups_data_total_inactive_count = UserGroup.query()\ - .filter(or_( - # generate multiple IN to fix limitation problems - *in_filter_generator(UserGroup.users_group_id, allowed_ids) - ))\ - .filter(UserGroup.users_group_active != true()).count() + user_groups_data_total_inactive_count = ( + UserGroup.query() + .filter( + or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(UserGroup.users_group_id, allowed_ids) + ) + ) + .filter(UserGroup.users_group_active != true()) + .count() + ) member_count = count(UserGroupMember.user_id) - base_q = Session.query( - UserGroup.users_group_name, - UserGroup.user_group_description, - UserGroup.users_group_active, - UserGroup.users_group_id, - UserGroup.group_data, - User, - member_count.label('member_count') - ) \ - .filter(or_( - # generate multiple IN to fix limitation problems - *in_filter_generator(UserGroup.users_group_id, allowed_ids) - )) \ - .outerjoin(UserGroupMember, UserGroupMember.users_group_id == UserGroup.users_group_id) \ - .join(User, User.user_id == UserGroup.user_id) \ + base_q = ( + Session.query( + UserGroup.users_group_name, + UserGroup.user_group_description, + UserGroup.users_group_active, + UserGroup.users_group_id, + UserGroup.group_data, + User, + member_count.label("member_count"), + ) + .filter( + or_( + # generate multiple IN to fix limitation problems + *in_filter_generator(UserGroup.users_group_id, allowed_ids) + ) + ) + .outerjoin(UserGroupMember, UserGroupMember.users_group_id == UserGroup.users_group_id) + .join(User, User.user_id == UserGroup.user_id) .group_by(UserGroup, User) + ) base_q_inactive = base_q.filter(UserGroup.users_group_active != true()) if search_q: - like_expression = u'%{}%'.format(safe_str(search_q)) - base_q = base_q.filter(or_( - UserGroup.users_group_name.ilike(like_expression), - )) + like_expression = "%{}%".format(safe_str(search_q)) + base_q = base_q.filter( + or_( + UserGroup.users_group_name.ilike(like_expression), + ) + ) base_q_inactive = base_q.filter(UserGroup.users_group_active != true()) user_groups_data_total_filtered_count = base_q.count() user_groups_data_total_filtered_inactive_count = base_q_inactive.count() sort_defined = False - if order_by == 'members_total': + if order_by == "members_total": sort_col = member_count sort_defined = True - elif order_by == 'user_username': + elif order_by == "user_username": sort_col = User.username else: sort_col = getattr(UserGroup, order_by, None) if sort_defined or sort_col: - if order_dir == 'asc': + if order_dir == "asc": sort_col = sort_col.asc() else: sort_col = sort_col.desc() @@ -164,87 +173,81 @@ class AdminUserGroupsView(BaseAppView, DataGridAppView): "members": user_gr.member_count, # NOTE(marcink): because of advanced query we # need to load it like that - "sync": UserGroup._load_sync( - UserGroup._load_group_data(user_gr.group_data)), + "sync": UserGroup._load_sync(UserGroup._load_group_data(user_gr.group_data)), "active": h.bool2icon(user_gr.users_group_active), "owner": user_profile(user_gr.User.username), - "action": user_group_actions( - user_gr.users_group_id, user_gr.users_group_name) + "action": user_group_actions(user_gr.users_group_id, user_gr.users_group_name), } user_groups_data.append(row) - data = ({ - 'draw': draw, - 'data': user_groups_data, - 'recordsTotal': user_groups_data_total_count, - 'recordsTotalInactive': user_groups_data_total_inactive_count, - 'recordsFiltered': user_groups_data_total_filtered_count, - 'recordsFilteredInactive': user_groups_data_total_filtered_inactive_count, - }) + data = { + "draw": draw, + "data": user_groups_data, + "recordsTotal": user_groups_data_total_count, + "recordsTotalInactive": user_groups_data_total_inactive_count, + "recordsFiltered": user_groups_data_total_filtered_count, + "recordsFilteredInactive": user_groups_data_total_filtered_inactive_count, + } return data @LoginRequired() - @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true') + @HasPermissionAnyDecorator("hg.admin", "hg.usergroup.create.true") def user_groups_new(self): c = self.load_default_context() return self._get_template_context(c) @LoginRequired() - @HasPermissionAnyDecorator('hg.admin', 'hg.usergroup.create.true') + @HasPermissionAnyDecorator("hg.admin", "hg.usergroup.create.true") @CSRFRequired() def user_groups_create(self): _ = self.request.translate c = self.load_default_context() users_group_form = UserGroupForm(self.request.translate)() - user_group_name = self.request.POST.get('users_group_name') + user_group_name = self.request.POST.get("users_group_name") try: form_result = users_group_form.to_python(dict(self.request.POST)) user_group = UserGroupModel().create( - name=form_result['users_group_name'], - description=form_result['user_group_description'], + name=form_result["users_group_name"], + description=form_result["user_group_description"], owner=self._rhodecode_user.user_id, - active=form_result['users_group_active']) + active=form_result["users_group_active"], + ) Session().flush() creation_data = user_group.get_api_data() - user_group_name = form_result['users_group_name'] + user_group_name = form_result["users_group_name"] - audit_logger.store_web( - 'user_group.create', action_data={'data': creation_data}, - user=self._rhodecode_user) + audit_logger.store_web("user_group.create", action_data={"data": creation_data}, user=self._rhodecode_user) user_group_link = h.link_to( - h.escape(user_group_name), - h.route_path( - 'edit_user_group', user_group_id=user_group.users_group_id)) - h.flash(h.literal(_('Created user group %(user_group_link)s') - % {'user_group_link': user_group_link}), - category='success') + h.escape(user_group_name), h.route_path("edit_user_group", user_group_id=user_group.users_group_id) + ) + h.flash( + h.literal(_("Created user group %(user_group_link)s") % {"user_group_link": user_group_link}), + category="success", + ) Session().commit() user_group_id = user_group.users_group_id except formencode.Invalid as errors: - data = render( - 'rhodecode:templates/admin/user_groups/user_group_add.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/user_groups/user_group_add.mako", self._get_template_context(c), self.request + ) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: log.exception("Exception creating user group") - h.flash(_('Error occurred during creation of user group %s') \ - % user_group_name, category='error') - raise HTTPFound(h.route_path('user_groups_new')) + h.flash(_("Error occurred during creation of user group %s") % user_group_name, category="error") + raise HTTPFound(h.route_path("user_groups_new")) PermissionModel().trigger_permission_flush() - raise HTTPFound( - h.route_path('edit_user_group', user_group_id=user_group_id)) + raise HTTPFound(h.route_path("edit_user_group", user_group_id=user_group_id)) diff --git a/rhodecode/apps/admin/views/users.py b/rhodecode/apps/admin/views/users.py index 65863914..28c749ec 100644 --- a/rhodecode/apps/admin/views/users.py +++ b/rhodecode/apps/admin/views/users.py @@ -35,82 +35,95 @@ from rhodecode.model.db import true, UserNotice from rhodecode.lib import audit_logger, rc_cache, auth from rhodecode.lib.exceptions import ( - UserCreationError, UserOwnsReposException, UserOwnsRepoGroupsException, - UserOwnsUserGroupsException, UserOwnsPullRequestsException, - UserOwnsArtifactsException, DefaultUserException) + UserCreationError, + UserOwnsReposException, + UserOwnsRepoGroupsException, + UserOwnsUserGroupsException, + UserOwnsPullRequestsException, + UserOwnsArtifactsException, + DefaultUserException, +) from rhodecode.lib import ext_json -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.lib import helpers as h from rhodecode.lib.helpers import SqlPage from rhodecode.lib.utils2 import safe_int, safe_str, AttributeDict from rhodecode.model.auth_token import AuthTokenModel from rhodecode.model.forms import ( - UserForm, UserIndividualPermissionsForm, UserPermissionsForm, - UserExtraEmailForm, UserExtraIpForm) + UserForm, + UserIndividualPermissionsForm, + UserPermissionsForm, + UserExtraEmailForm, + UserExtraIpForm, +) from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.ssh_key import SshKeyModel from rhodecode.model.user import UserModel from rhodecode.model.user_group import UserGroupModel from rhodecode.model.db import ( - or_, coalesce,IntegrityError, User, UserGroup, UserIpMap, UserEmailMap, - UserApiKeys, UserSshKeys, RepoGroup) + or_, + coalesce, + IntegrityError, + User, + UserGroup, + UserIpMap, + UserEmailMap, + UserApiKeys, + UserSshKeys, + RepoGroup, +) from rhodecode.model.meta import Session log = logging.getLogger(__name__) class AdminUsersView(BaseAppView, DataGridAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def users_list(self): c = self.load_default_context() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def users_list_data(self): self.load_default_context() column_map = { - 'first_name': 'name', - 'last_name': 'lastname', + "first_name": "name", + "last_name": "lastname", } draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) - _render = self.request.get_partial_renderer( - 'rhodecode:templates/data_table/_dt_elements.mako') + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) + _render = self.request.get_partial_renderer("rhodecode:templates/data_table/_dt_elements.mako") def user_actions(user_id, username): return _render("user_actions", user_id, username) - users_data_total_count = User.query()\ - .filter(User.username != User.DEFAULT_USER) \ - .count() + users_data_total_count = User.query().filter(User.username != User.DEFAULT_USER).count() - users_data_total_inactive_count = User.query()\ - .filter(User.username != User.DEFAULT_USER) \ - .filter(User.active != true())\ - .count() + users_data_total_inactive_count = ( + User.query().filter(User.username != User.DEFAULT_USER).filter(User.active != true()).count() + ) # json generate base_q = User.query().filter(User.username != User.DEFAULT_USER) base_inactive_q = base_q.filter(User.active != true()) if search_q: - like_expression = '%{}%'.format(safe_str(search_q)) - base_q = base_q.filter(or_( - User.username.ilike(like_expression), - User._email.ilike(like_expression), - User.name.ilike(like_expression), - User.lastname.ilike(like_expression), - )) + like_expression = "%{}%".format(safe_str(search_q)) + base_q = base_q.filter( + or_( + User.username.ilike(like_expression), + User._email.ilike(like_expression), + User.name.ilike(like_expression), + User.lastname.ilike(like_expression), + ) + ) base_inactive_q = base_q.filter(User.active != true()) users_data_total_filtered_count = base_q.count() @@ -118,14 +131,14 @@ class AdminUsersView(BaseAppView, DataGridAppView): sort_col = getattr(User, order_by, None) if sort_col: - if order_dir == 'asc': + if order_dir == "asc": # handle null values properly to order by NULL last - if order_by in ['last_activity']: + if order_by in ["last_activity"]: sort_col = coalesce(sort_col, datetime.date.max) sort_col = sort_col.asc() else: # handle null values properly to order by NULL last - if order_by in ['last_activity']: + if order_by in ["last_activity"]: sort_col = coalesce(sort_col, datetime.date.min) sort_col = sort_col.desc() @@ -136,43 +149,45 @@ class AdminUsersView(BaseAppView, DataGridAppView): users_data = [] for user in users_list: - users_data.append({ - "username": h.gravatar_with_user(self.request, user.username), - "email": user.email, - "first_name": user.first_name, - "last_name": user.last_name, - "last_login": h.format_date(user.last_login), - "last_activity": h.format_date(user.last_activity), - "active": h.bool2icon(user.active), - "active_raw": user.active, - "admin": h.bool2icon(user.admin), - "extern_type": user.extern_type, - "extern_name": user.extern_name, - "action": user_actions(user.user_id, user.username), - }) - data = ({ - 'draw': draw, - 'data': users_data, - 'recordsTotal': users_data_total_count, - 'recordsFiltered': users_data_total_filtered_count, - 'recordsTotalInactive': users_data_total_inactive_count, - 'recordsFilteredInactive': users_data_total_filtered_inactive_count - }) + users_data.append( + { + "username": h.gravatar_with_user(self.request, user.username), + "email": user.email, + "first_name": user.first_name, + "last_name": user.last_name, + "last_login": h.format_date(user.last_login), + "last_activity": h.format_date(user.last_activity), + "active": h.bool2icon(user.active), + "active_raw": user.active, + "admin": h.bool2icon(user.admin), + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "action": user_actions(user.user_id, user.username), + } + ) + data = { + "draw": draw, + "data": users_data, + "recordsTotal": users_data_total_count, + "recordsFiltered": users_data_total_filtered_count, + "recordsTotalInactive": users_data_total_inactive_count, + "recordsFilteredInactive": users_data_total_filtered_inactive_count, + } return data def _set_personal_repo_group_template_vars(self, c_obj): - DummyUser = AttributeDict({ - 'username': '${username}', - 'user_id': '${user_id}', - }) - c_obj.default_create_repo_group = RepoGroupModel() \ - .get_default_create_personal_repo_group() - c_obj.personal_repo_group_name = RepoGroupModel() \ - .get_personal_group_name(DummyUser) + DummyUser = AttributeDict( + { + "username": "${username}", + "user_id": "${user_id}", + } + ) + c_obj.default_create_repo_group = RepoGroupModel().get_default_create_personal_repo_group() + c_obj.personal_repo_group_name = RepoGroupModel().get_personal_group_name(DummyUser) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def users_new(self): _ = self.request.translate c = self.load_default_context() @@ -181,7 +196,7 @@ class AdminUsersView(BaseAppView, DataGridAppView): return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def users_create(self): _ = self.request.translate @@ -194,39 +209,33 @@ class AdminUsersView(BaseAppView, DataGridAppView): user = user_model.create(form_result) Session().flush() creation_data = user.get_api_data() - username = form_result['username'] + username = form_result["username"] - audit_logger.store_web( - 'user.create', action_data={'data': creation_data}, - user=c.rhodecode_user) + audit_logger.store_web("user.create", action_data={"data": creation_data}, user=c.rhodecode_user) - user_link = h.link_to( - h.escape(username), - h.route_path('user_edit', user_id=user.user_id)) - h.flash(h.literal(_('Created user %(user_link)s') - % {'user_link': user_link}), category='success') + user_link = h.link_to(h.escape(username), h.route_path("user_edit", user_id=user.user_id)) + h.flash(h.literal(_("Created user %(user_link)s") % {"user_link": user_link}), category="success") Session().commit() except formencode.Invalid as errors: self._set_personal_repo_group_template_vars(c) - data = render( - 'rhodecode:templates/admin/users/user_add.mako', - self._get_template_context(c), self.request) + data = render("rhodecode:templates/admin/users/user_add.mako", self._get_template_context(c), self.request) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except UserCreationError as e: - h.flash(safe_str(e), 'error') + h.flash(safe_str(e), "error") except Exception: log.exception("Exception creation of user") - h.flash(_('Error occurred during creation of user %s') - % self.request.POST.get('username'), category='error') - raise HTTPFound(h.route_path('users')) + h.flash( + _("Error occurred during creation of user %s") % self.request.POST.get("username"), category="error" + ) + raise HTTPFound(h.route_path("users")) class UsersView(UserAppView): @@ -242,7 +251,7 @@ class UsersView(UserAppView): for plugin in authn_registry.get_plugins_for_authentication(): if isinstance(plugin, RhodeCodeExternalAuthPlugin): valid_plugins.append(plugin) - elif plugin.name == 'rhodecode': + elif plugin.name == "rhodecode": valid_plugins.append(plugin) # extend our choices if user has set a bound plugin which isn't enabled at the @@ -255,8 +264,7 @@ class UsersView(UserAppView): valid_plugins.append(plugin) except Exception: - log.exception( - f'Could not extend user plugins with `{extern_type}`') + log.exception(f"Could not extend user plugins with `{extern_type}`") return valid_plugins def load_default_context(self): @@ -265,33 +273,30 @@ class UsersView(UserAppView): c = self._get_local_tmpl_context() c.allow_scoped_tokens = self.ALLOW_SCOPED_TOKENS c.allowed_languages = [ - ('en', 'English (en)'), - ('de', 'German (de)'), - ('fr', 'French (fr)'), - ('it', 'Italian (it)'), - ('ja', 'Japanese (ja)'), - ('pl', 'Polish (pl)'), - ('pt', 'Portuguese (pt)'), - ('ru', 'Russian (ru)'), - ('zh', 'Chinese (zh)'), + ("en", "English (en)"), + ("de", "German (de)"), + ("fr", "French (fr)"), + ("it", "Italian (it)"), + ("ja", "Japanese (ja)"), + ("pl", "Polish (pl)"), + ("pt", "Portuguese (pt)"), + ("ru", "Russian (ru)"), + ("zh", "Chinese (zh)"), ] - c.allowed_extern_types = [ - (x.uid, x.get_display_name()) for x in self.get_auth_plugins() - ] - perms = req.registry.settings.get('available_permissions') + c.allowed_extern_types = [(x.uid, x.get_display_name()) for x in self.get_auth_plugins()] + perms = req.registry.settings.get("available_permissions") if not perms: # inject info about available permissions auth.set_available_permissions(req.registry.settings) - c.available_permissions = req.registry.settings['available_permissions'] - PermissionModel().set_global_permission_choices( - c, gettext_translator=req.translate) + c.available_permissions = req.registry.settings["available_permissions"] + PermissionModel().set_global_permission_choices(c, gettext_translator=req.translate) return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_update(self): _ = self.request.translate @@ -300,60 +305,56 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - c.active = 'profile' + c.active = "profile" c.extern_type = c.user.extern_type c.extern_name = c.user.extern_name c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) available_languages = [x[0] for x in c.allowed_languages] - _form = UserForm(self.request.translate, edit=True, - available_languages=available_languages, - old_data={'user_id': user_id, - 'email': c.user.email})() + _form = UserForm( + self.request.translate, + edit=True, + available_languages=available_languages, + old_data={"user_id": user_id, "email": c.user.email}, + )() - c.edit_mode = self.request.POST.get('edit') == '1' + c.edit_mode = self.request.POST.get("edit") == "1" form_result = {} old_values = c.user.get_api_data() try: form_result = _form.to_python(dict(self.request.POST)) - skip_attrs = ['extern_name'] + skip_attrs = ["extern_name"] # TODO: plugin should define if username can be updated if c.extern_type != "rhodecode" and not c.edit_mode: # forbid updating username for external accounts - skip_attrs.append('username') + skip_attrs.append("username") - UserModel().update_user( - user_id, skip_attrs=skip_attrs, **form_result) + UserModel().update_user(user_id, skip_attrs=skip_attrs, **form_result) - audit_logger.store_web( - 'user.edit', action_data={'old_data': old_values}, - user=c.rhodecode_user) + audit_logger.store_web("user.edit", action_data={"old_data": old_values}, user=c.rhodecode_user) Session().commit() - h.flash(_('User updated successfully'), category='success') + h.flash(_("User updated successfully"), category="success") except formencode.Invalid as errors: - data = render( - 'rhodecode:templates/admin/users/user_edit.mako', - self._get_template_context(c), self.request) + data = render("rhodecode:templates/admin/users/user_edit.mako", self._get_template_context(c), self.request) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except UserCreationError as e: - h.flash(safe_str(e), 'error') + h.flash(safe_str(e), "error") except Exception: log.exception("Exception updating user") - h.flash(_('Error occurred during update of user %s') - % form_result.get('username'), category='error') - raise HTTPFound(h.route_path('user_edit', user_id=user_id)) + h.flash(_("Error occurred during update of user %s") % form_result.get("username"), category="error") + raise HTTPFound(h.route_path("user_edit", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_delete(self): _ = self.request.translate @@ -375,74 +376,63 @@ class UsersView(UserAppView): # calls for flash of handle based on handle case detach or delete def set_handle_flash_repos(): handle = handle_repos - if handle == 'detach': - h.flash(_('Detached %s repositories') % _repos, - category='success') - elif handle == 'delete': - h.flash(_('Deleted %s repositories') % _repos, - category='success') + if handle == "detach": + h.flash(_("Detached %s repositories") % _repos, category="success") + elif handle == "delete": + h.flash(_("Deleted %s repositories") % _repos, category="success") def set_handle_flash_repo_groups(): handle = handle_repo_groups - if handle == 'detach': - h.flash(_('Detached %s repository groups') % _repo_groups, - category='success') - elif handle == 'delete': - h.flash(_('Deleted %s repository groups') % _repo_groups, - category='success') + if handle == "detach": + h.flash(_("Detached %s repository groups") % _repo_groups, category="success") + elif handle == "delete": + h.flash(_("Deleted %s repository groups") % _repo_groups, category="success") def set_handle_flash_user_groups(): handle = handle_user_groups - if handle == 'detach': - h.flash(_('Detached %s user groups') % _user_groups, - category='success') - elif handle == 'delete': - h.flash(_('Deleted %s user groups') % _user_groups, - category='success') + if handle == "detach": + h.flash(_("Detached %s user groups") % _user_groups, category="success") + elif handle == "delete": + h.flash(_("Deleted %s user groups") % _user_groups, category="success") def set_handle_flash_pull_requests(): handle = handle_pull_requests - if handle == 'detach': - h.flash(_('Detached %s pull requests') % _pull_requests, - category='success') - elif handle == 'delete': - h.flash(_('Deleted %s pull requests') % _pull_requests, - category='success') + if handle == "detach": + h.flash(_("Detached %s pull requests") % _pull_requests, category="success") + elif handle == "delete": + h.flash(_("Deleted %s pull requests") % _pull_requests, category="success") def set_handle_flash_artifacts(): handle = handle_artifacts - if handle == 'detach': - h.flash(_('Detached %s artifacts') % _artifacts, - category='success') - elif handle == 'delete': - h.flash(_('Deleted %s artifacts') % _artifacts, - category='success') + if handle == "detach": + h.flash(_("Detached %s artifacts") % _artifacts, category="success") + elif handle == "delete": + h.flash(_("Deleted %s artifacts") % _artifacts, category="success") handle_user = User.get_first_super_admin() - handle_user_id = safe_int(self.request.POST.get('detach_user_id')) + handle_user_id = safe_int(self.request.POST.get("detach_user_id")) if handle_user_id: # NOTE(marcink): we get new owner for objects... handle_user = User.get_or_404(handle_user_id) - if _repos and self.request.POST.get('user_repos'): - handle_repos = self.request.POST['user_repos'] + if _repos and self.request.POST.get("user_repos"): + handle_repos = self.request.POST["user_repos"] - if _repo_groups and self.request.POST.get('user_repo_groups'): - handle_repo_groups = self.request.POST['user_repo_groups'] + if _repo_groups and self.request.POST.get("user_repo_groups"): + handle_repo_groups = self.request.POST["user_repo_groups"] - if _user_groups and self.request.POST.get('user_user_groups'): - handle_user_groups = self.request.POST['user_user_groups'] + if _user_groups and self.request.POST.get("user_user_groups"): + handle_user_groups = self.request.POST["user_user_groups"] - if _pull_requests and self.request.POST.get('user_pull_requests'): - handle_pull_requests = self.request.POST['user_pull_requests'] + if _pull_requests and self.request.POST.get("user_pull_requests"): + handle_pull_requests = self.request.POST["user_pull_requests"] - if _artifacts and self.request.POST.get('user_artifacts'): - handle_artifacts = self.request.POST['user_artifacts'] + if _artifacts and self.request.POST.get("user_artifacts"): + handle_artifacts = self.request.POST["user_artifacts"] old_values = c.user.get_api_data() try: - UserModel().delete( c.user, handle_repos=handle_repos, @@ -450,12 +440,10 @@ class UsersView(UserAppView): handle_user_groups=handle_user_groups, handle_pull_requests=handle_pull_requests, handle_artifacts=handle_artifacts, - handle_new_owner=handle_user + handle_new_owner=handle_user, ) - audit_logger.store_web( - 'user.delete', action_data={'old_data': old_values}, - user=c.rhodecode_user) + audit_logger.store_web("user.delete", action_data={"old_data": old_values}, user=c.rhodecode_user) Session().commit() set_handle_flash_repos() @@ -463,48 +451,44 @@ class UsersView(UserAppView): set_handle_flash_user_groups() set_handle_flash_pull_requests() set_handle_flash_artifacts() - username = h.escape(old_values['username']) - h.flash(_('Successfully deleted user `{}`').format(username), category='success') - except (UserOwnsReposException, UserOwnsRepoGroupsException, - UserOwnsUserGroupsException, UserOwnsPullRequestsException, - UserOwnsArtifactsException, DefaultUserException) as e: - - h.flash(safe_str(e), category='warning') + username = h.escape(old_values["username"]) + h.flash(_("Successfully deleted user `{}`").format(username), category="success") + except ( + UserOwnsReposException, + UserOwnsRepoGroupsException, + UserOwnsUserGroupsException, + UserOwnsPullRequestsException, + UserOwnsArtifactsException, + DefaultUserException, + ) as e: + h.flash(safe_str(e), category="warning") except Exception: log.exception("Exception during deletion of user") - h.flash(_('An error occurred during deletion of user'), - category='error') - raise HTTPFound(h.route_path('users')) + h.flash(_("An error occurred during deletion of user"), category="error") + raise HTTPFound(h.route_path("users")) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_edit(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'profile' + c.active = "profile" c.extern_type = c.user.extern_type c.extern_name = c.user.extern_name c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) - c.edit_mode = self.request.GET.get('edit') == '1' + c.edit_mode = self.request.GET.get("edit") == "1" defaults = c.user.get_dict() - defaults.update({'language': c.user.user_data.get('language')}) + defaults.update({"language": c.user.user_data.get("language")}) - data = render( - 'rhodecode:templates/admin/users/user_edit.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/users/user_edit.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_edit_advanced(self): _ = self.request.translate c = self.load_default_context() @@ -513,18 +497,15 @@ class UsersView(UserAppView): c.user = self.db_user c.detach_user = User.get_first_super_admin() - detach_user_id = safe_int(self.request.GET.get('detach_user_id')) + detach_user_id = safe_int(self.request.GET.get("detach_user_id")) if detach_user_id: c.detach_user = User.get_or_404(detach_user_id) - c.active = 'advanced' + c.active = "advanced" c.personal_repo_group = RepoGroup.get_user_personal_repo_group(user_id) - c.personal_repo_group_name = RepoGroupModel()\ - .get_personal_group_name(c.user) + c.personal_repo_group_name = RepoGroupModel().get_personal_group_name(c.user) - c.user_to_review_rules = sorted( - (x.user for x in c.user.user_review_rules), - key=lambda u: u.username.lower()) + c.user_to_review_rules = sorted((x.user for x in c.user.user_review_rules), key=lambda u: u.username.lower()) defaults = c.user.get_dict() @@ -532,61 +513,50 @@ class UsersView(UserAppView): # reviewer. has_review = len(c.user.reviewer_pull_requests) c.can_delete_user = not has_review - c.can_delete_user_message = '' - inactive_link = h.link_to( - 'inactive', h.route_path('user_edit', user_id=user_id, _anchor='active')) + c.can_delete_user_message = "" + inactive_link = h.link_to("inactive", h.route_path("user_edit", user_id=user_id, _anchor="active")) if has_review == 1: - c.can_delete_user_message = h.literal(_( - 'The user participates as reviewer in {} pull request and ' - 'cannot be deleted. \nYou can set the user to ' - '"{}" instead of deleting it.').format( - has_review, inactive_link)) + c.can_delete_user_message = h.literal( + _( + "The user participates as reviewer in {} pull request and " + "cannot be deleted. \nYou can set the user to " + '"{}" instead of deleting it.' + ).format(has_review, inactive_link) + ) elif has_review: - c.can_delete_user_message = h.literal(_( - 'The user participates as reviewer in {} pull requests and ' - 'cannot be deleted. \nYou can set the user to ' - '"{}" instead of deleting it.').format( - has_review, inactive_link)) + c.can_delete_user_message = h.literal( + _( + "The user participates as reviewer in {} pull requests and " + "cannot be deleted. \nYou can set the user to " + '"{}" instead of deleting it.' + ).format(has_review, inactive_link) + ) - data = render( - 'rhodecode:templates/admin/users/user_edit.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/users/user_edit.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_edit_global_perms(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'global_perms' + c.active = "global_perms" c.default_user = User.get_default_user() defaults = c.user.get_dict() - defaults.update(c.default_user.get_default_perms(suffix='_inherited')) + defaults.update(c.default_user.get_default_perms(suffix="_inherited")) defaults.update(c.default_user.get_default_perms()) defaults.update(c.user.get_default_perms()) - data = render( - 'rhodecode:templates/admin/users/user_edit.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/users/user_edit.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_edit_global_perms_update(self): _ = self.request.translate @@ -595,12 +565,12 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - c.active = 'global_perms' + c.active = "global_perms" try: # first stage that verifies the checkbox _form = UserIndividualPermissionsForm(self.request.translate) form_result = _form.to_python(dict(self.request.POST)) - inherit_perms = form_result['inherit_default_permissions'] + inherit_perms = form_result["inherit_default_permissions"] c.user.inherit_default_permissions = inherit_perms Session().add(c.user) @@ -613,10 +583,11 @@ class UsersView(UserAppView): [x[0] for x in c.repo_group_create_choices], [x[0] for x in c.user_group_create_choices], [x[0] for x in c.fork_choices], - [x[0] for x in c.inherit_default_permission_choices])() + [x[0] for x in c.inherit_default_permission_choices], + )() form_result = _form.to_python(dict(self.request.POST)) - form_result.update({'perm_user_id': c.user.user_id}) + form_result.update({"perm_user_id": c.user.user_id}) PermissionModel().update_user_permissions(form_result) @@ -625,33 +596,29 @@ class UsersView(UserAppView): Session().commit() - h.flash(_('User global permissions updated successfully'), - category='success') + h.flash(_("User global permissions updated successfully"), category="success") except formencode.Invalid as errors: - data = render( - 'rhodecode:templates/admin/users/user_edit.mako', - self._get_template_context(c), self.request) + data = render("rhodecode:templates/admin/users/user_edit.mako", self._get_template_context(c), self.request) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.unpack_errors() or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: log.exception("Exception during permissions saving") - h.flash(_('An error occurred during permissions saving'), - category='error') + h.flash(_("An error occurred during permissions saving"), category="error") affected_user_ids = [user_id] PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound(h.route_path('user_edit_global_perms', user_id=user_id)) + raise HTTPFound(h.route_path("user_edit_global_perms", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_enable_force_password_reset(self): _ = self.request.translate @@ -663,21 +630,19 @@ class UsersView(UserAppView): try: c.user.update_userdata(force_password_change=True) - msg = _('Force password change enabled for user') - audit_logger.store_web('user.edit.password_reset.enabled', - user=c.rhodecode_user) + msg = _("Force password change enabled for user") + audit_logger.store_web("user.edit.password_reset.enabled", user=c.rhodecode_user) Session().commit() - h.flash(msg, category='success') + h.flash(msg, category="success") except Exception: log.exception("Exception during password reset for user") - h.flash(_('An error occurred during password reset for user'), - category='error') + h.flash(_("An error occurred during password reset for user"), category="error") - raise HTTPFound(h.route_path('user_edit_advanced', user_id=user_id)) + raise HTTPFound(h.route_path("user_edit_advanced", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_disable_force_password_reset(self): _ = self.request.translate @@ -689,22 +654,19 @@ class UsersView(UserAppView): try: c.user.update_userdata(force_password_change=False) - msg = _('Force password change disabled for user') - audit_logger.store_web( - 'user.edit.password_reset.disabled', - user=c.rhodecode_user) + msg = _("Force password change disabled for user") + audit_logger.store_web("user.edit.password_reset.disabled", user=c.rhodecode_user) Session().commit() - h.flash(msg, category='success') + h.flash(msg, category="success") except Exception: log.exception("Exception during password reset for user") - h.flash(_('An error occurred during password reset for user'), - category='error') + h.flash(_("An error occurred during password reset for user"), category="error") - raise HTTPFound(h.route_path('user_edit_advanced', user_id=user_id)) + raise HTTPFound(h.route_path("user_edit_advanced", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_notice_dismiss(self): _ = self.request.translate @@ -712,11 +674,14 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - user_notice_id = safe_int(self.request.POST.get('notice_id')) - notice = UserNotice().query()\ - .filter(UserNotice.user_id == user_id)\ - .filter(UserNotice.user_notice_id == user_notice_id)\ + user_notice_id = safe_int(self.request.POST.get("notice_id")) + notice = ( + UserNotice() + .query() + .filter(UserNotice.user_id == user_id) + .filter(UserNotice.user_notice_id == user_notice_id) .scalar() + ) read = False if notice: notice.notice_read = True @@ -724,10 +689,10 @@ class UsersView(UserAppView): Session().commit() read = True - return {'notice': user_notice_id, 'read': read} + return {"notice": user_notice_id, "read": read} @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_create_personal_repo_group(self): """ @@ -741,84 +706,72 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - personal_repo_group = RepoGroup.get_user_personal_repo_group( - c.user.user_id) + personal_repo_group = RepoGroup.get_user_personal_repo_group(c.user.user_id) if personal_repo_group: - raise HTTPFound(h.route_path('user_edit_advanced', user_id=user_id)) + raise HTTPFound(h.route_path("user_edit_advanced", user_id=user_id)) personal_repo_group_name = RepoGroupModel().get_personal_group_name(c.user) - named_personal_group = RepoGroup.get_by_group_name( - personal_repo_group_name) + named_personal_group = RepoGroup.get_by_group_name(personal_repo_group_name) try: - if named_personal_group and named_personal_group.user_id == c.user.user_id: # migrate the same named group, and mark it as personal named_personal_group.personal = True Session().add(named_personal_group) Session().commit() - msg = _('Linked repository group `{}` as personal'.format( - personal_repo_group_name)) - h.flash(msg, category='success') + msg = _("Linked repository group `{}` as personal".format(personal_repo_group_name)) + h.flash(msg, category="success") elif not named_personal_group: RepoGroupModel().create_personal_repo_group(c.user) - msg = _('Created repository group `{}`'.format( - personal_repo_group_name)) - h.flash(msg, category='success') + msg = _("Created repository group `{}`".format(personal_repo_group_name)) + h.flash(msg, category="success") else: - msg = _('Repository group `{}` is already taken'.format( - personal_repo_group_name)) - h.flash(msg, category='warning') + msg = _("Repository group `{}` is already taken".format(personal_repo_group_name)) + h.flash(msg, category="warning") except Exception: log.exception("Exception during repository group creation") - msg = _( - 'An error occurred during repository group creation for user') - h.flash(msg, category='error') + msg = _("An error occurred during repository group creation for user") + h.flash(msg, category="error") Session().rollback() - raise HTTPFound(h.route_path('user_edit_advanced', user_id=user_id)) + raise HTTPFound(h.route_path("user_edit_advanced", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def auth_tokens(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'auth_tokens' + c.active = "auth_tokens" c.lifetime_values = AuthTokenModel.get_lifetime_values(translator=_) - c.role_values = [ - (x, AuthTokenModel.cls._get_role_name(x)) - for x in AuthTokenModel.cls.ROLES] + c.role_values = [(x, AuthTokenModel.cls._get_role_name(x)) for x in AuthTokenModel.cls.ROLES] c.role_options = [(c.role_values, _("Role"))] - c.user_auth_tokens = AuthTokenModel().get_auth_tokens( - c.user.user_id, show_expired=True) + c.user_auth_tokens = AuthTokenModel().get_auth_tokens(c.user.user_id, show_expired=True) c.role_vcs = AuthTokenModel.cls.ROLE_VCS return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def auth_tokens_view(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - auth_token_id = self.request.POST.get('auth_token_id') + auth_token_id = self.request.POST.get("auth_token_id") if auth_token_id: token = UserApiKeys.get_or_404(auth_token_id) - return { - 'auth_token': token.api_key - } + return {"auth_token": token.api_key} def maybe_attach_token_scope(self, token): # implemented in EE edition pass @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def auth_tokens_add(self): _ = self.request.translate @@ -828,27 +781,31 @@ class UsersView(UserAppView): c.user = self.db_user user_data = c.user.get_api_data() - lifetime = safe_int(self.request.POST.get('lifetime'), -1) - description = self.request.POST.get('description') - role = self.request.POST.get('role') + lifetime = safe_int(self.request.POST.get("lifetime"), -1) + description = self.request.POST.get("description") + role = self.request.POST.get("role") token = UserModel().add_auth_token( user=c.user.user_id, - lifetime_minutes=lifetime, role=role, description=description, - scope_callback=self.maybe_attach_token_scope) + lifetime_minutes=lifetime, + role=role, + description=description, + scope_callback=self.maybe_attach_token_scope, + ) token_data = token.get_api_data() audit_logger.store_web( - 'user.edit.token.add', action_data={ - 'data': {'token': token_data, 'user': user_data}}, - user=self._rhodecode_user, ) + "user.edit.token.add", + action_data={"data": {"token": token_data, "user": user_data}}, + user=self._rhodecode_user, + ) Session().commit() - h.flash(_("Auth token successfully created"), category='success') - return HTTPFound(h.route_path('edit_user_auth_tokens', user_id=user_id)) + h.flash(_("Auth token successfully created"), category="success") + return HTTPFound(h.route_path("edit_user_auth_tokens", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def auth_tokens_delete(self): _ = self.request.translate @@ -859,7 +816,7 @@ class UsersView(UserAppView): user_data = c.user.get_api_data() - del_auth_token = self.request.POST.get('del_auth_token') + del_auth_token = self.request.POST.get("del_auth_token") if del_auth_token: token = UserApiKeys.get_or_404(del_auth_token) @@ -867,45 +824,44 @@ class UsersView(UserAppView): AuthTokenModel().delete(del_auth_token, c.user.user_id) audit_logger.store_web( - 'user.edit.token.delete', action_data={ - 'data': {'token': token_data, 'user': user_data}}, - user=self._rhodecode_user,) + "user.edit.token.delete", + action_data={"data": {"token": token_data, "user": user_data}}, + user=self._rhodecode_user, + ) Session().commit() - h.flash(_("Auth token successfully deleted"), category='success') + h.flash(_("Auth token successfully deleted"), category="success") - return HTTPFound(h.route_path('edit_user_auth_tokens', user_id=user_id)) + return HTTPFound(h.route_path("edit_user_auth_tokens", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def ssh_keys(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'ssh_keys' - c.default_key = self.request.GET.get('default_key') + c.active = "ssh_keys" + c.default_key = self.request.GET.get("default_key") c.user_ssh_keys = SshKeyModel().get_ssh_keys(c.user.user_id) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def ssh_keys_generate_keypair(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'ssh_keys_generate' - comment = 'RhodeCode-SSH {}'.format(c.user.email or '') - private_format = self.request.GET.get('private_format') \ - or SshKeyModel.DEFAULT_PRIVATE_KEY_FORMAT - c.private, c.public = SshKeyModel().generate_keypair( - comment=comment, private_format=private_format) + c.active = "ssh_keys_generate" + comment = "RhodeCode-SSH {}".format(c.user.email or "") + private_format = self.request.GET.get("private_format") or SshKeyModel.DEFAULT_PRIVATE_KEY_FORMAT + c.private, c.public = SshKeyModel().generate_keypair(comment=comment, private_format=private_format) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def ssh_keys_add(self): _ = self.request.translate @@ -915,48 +871,44 @@ class UsersView(UserAppView): c.user = self.db_user user_data = c.user.get_api_data() - key_data = self.request.POST.get('key_data') - description = self.request.POST.get('description') + key_data = self.request.POST.get("key_data") + description = self.request.POST.get("description") - fingerprint = 'unknown' + fingerprint = "unknown" try: if not key_data: - raise ValueError('Please add a valid public key') + raise ValueError("Please add a valid public key") key = SshKeyModel().parse_key(key_data.strip()) fingerprint = key.hash_md5() - ssh_key = SshKeyModel().create( - c.user.user_id, fingerprint, key.keydata, description) + ssh_key = SshKeyModel().create(c.user.user_id, fingerprint, key.keydata, description) ssh_key_data = ssh_key.get_api_data() audit_logger.store_web( - 'user.edit.ssh_key.add', action_data={ - 'data': {'ssh_key': ssh_key_data, 'user': user_data}}, - user=self._rhodecode_user, ) + "user.edit.ssh_key.add", + action_data={"data": {"ssh_key": ssh_key_data, "user": user_data}}, + user=self._rhodecode_user, + ) Session().commit() # Trigger an event on change of keys. trigger(SshKeyFileChangeEvent(), self.request.registry) - h.flash(_("Ssh Key successfully created"), category='success') + h.flash(_("Ssh Key successfully created"), category="success") except IntegrityError: log.exception("Exception during ssh key saving") - err = 'Such key with fingerprint `{}` already exists, ' \ - 'please use a different one'.format(fingerprint) - h.flash(_('An error occurred during ssh key saving: {}').format(err), - category='error') + err = "Such key with fingerprint `{}` already exists, please use a different one".format(fingerprint) + h.flash(_("An error occurred during ssh key saving: {}").format(err), category="error") except Exception as e: log.exception("Exception during ssh key saving") - h.flash(_('An error occurred during ssh key saving: {}').format(e), - category='error') + h.flash(_("An error occurred during ssh key saving: {}").format(e), category="error") - return HTTPFound( - h.route_path('edit_user_ssh_keys', user_id=user_id)) + return HTTPFound(h.route_path("edit_user_ssh_keys", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def ssh_keys_delete(self): _ = self.request.translate @@ -967,7 +919,7 @@ class UsersView(UserAppView): user_data = c.user.get_api_data() - del_ssh_key = self.request.POST.get('del_ssh_key') + del_ssh_key = self.request.POST.get("del_ssh_key") if del_ssh_key: ssh_key = UserSshKeys.get_or_404(del_ssh_key) @@ -975,31 +927,31 @@ class UsersView(UserAppView): SshKeyModel().delete(del_ssh_key, c.user.user_id) audit_logger.store_web( - 'user.edit.ssh_key.delete', action_data={ - 'data': {'ssh_key': ssh_key_data, 'user': user_data}}, - user=self._rhodecode_user,) + "user.edit.ssh_key.delete", + action_data={"data": {"ssh_key": ssh_key_data, "user": user_data}}, + user=self._rhodecode_user, + ) Session().commit() # Trigger an event on change of keys. trigger(SshKeyFileChangeEvent(), self.request.registry) - h.flash(_("Ssh key successfully deleted"), category='success') + h.flash(_("Ssh key successfully deleted"), category="success") - return HTTPFound(h.route_path('edit_user_ssh_keys', user_id=user_id)) + return HTTPFound(h.route_path("edit_user_ssh_keys", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def emails(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'emails' - c.user_email_map = UserEmailMap.query() \ - .filter(UserEmailMap.user == c.user).all() + c.active = "emails" + c.user_email_map = UserEmailMap.query().filter(UserEmailMap.user == c.user).all() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def emails_add(self): _ = self.request.translate @@ -1008,37 +960,32 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - email = self.request.POST.get('new_email') + email = self.request.POST.get("new_email") user_data = c.user.get_api_data() try: - form = UserExtraEmailForm(self.request.translate)() - data = form.to_python({'email': email}) - email = data['email'] + data = form.to_python({"email": email}) + email = data["email"] UserModel().add_extra_email(c.user.user_id, email) audit_logger.store_web( - 'user.edit.email.add', - action_data={'email': email, 'user': user_data}, - user=self._rhodecode_user) + "user.edit.email.add", action_data={"email": email, "user": user_data}, user=self._rhodecode_user + ) Session().commit() - h.flash(_("Added new email address `%s` for user account") % email, - category='success') + h.flash(_("Added new email address `%s` for user account") % email, category="success") except formencode.Invalid as error: - msg = error.unpack_errors()['email'] - h.flash(h.escape(msg), category='error') + msg = error.unpack_errors()["email"] + h.flash(h.escape(msg), category="error") except IntegrityError: log.warning("Email %s already exists", email) - h.flash(_('Email `{}` is already registered for another user.').format(email), - category='error') + h.flash(_("Email `{}` is already registered for another user.").format(email), category="error") except Exception: log.exception("Exception during email saving") - h.flash(_('An error occurred during email saving'), - category='error') - raise HTTPFound(h.route_path('edit_user_emails', user_id=user_id)) + h.flash(_("An error occurred during email saving"), category="error") + raise HTTPFound(h.route_path("edit_user_emails", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def emails_delete(self): _ = self.request.translate @@ -1047,40 +994,36 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - email_id = self.request.POST.get('del_email_id') + email_id = self.request.POST.get("del_email_id") user_model = UserModel() email = UserEmailMap.query().get(email_id).email user_data = c.user.get_api_data() user_model.delete_extra_email(c.user.user_id, email_id) audit_logger.store_web( - 'user.edit.email.delete', - action_data={'email': email, 'user': user_data}, - user=self._rhodecode_user) + "user.edit.email.delete", action_data={"email": email, "user": user_data}, user=self._rhodecode_user + ) Session().commit() - h.flash(_("Removed email address from user account"), - category='success') - raise HTTPFound(h.route_path('edit_user_emails', user_id=user_id)) + h.flash(_("Removed email address from user account"), category="success") + raise HTTPFound(h.route_path("edit_user_emails", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def ips(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'ips' - c.user_ip_map = UserIpMap.query() \ - .filter(UserIpMap.user == c.user).all() + c.active = "ips" + c.user_ip_map = UserIpMap.query().filter(UserIpMap.user == c.user).all() c.inherit_default_ips = c.user.inherit_default_permissions - c.default_user_ip_map = UserIpMap.query() \ - .filter(UserIpMap.user == User.get_default_user()).all() + c.default_user_ip_map = UserIpMap.query().filter(UserIpMap.user == User.get_default_user()).all() return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() # NOTE(marcink): this view is allowed for default users, as we can # edit their IP white list @@ -1092,48 +1035,42 @@ class UsersView(UserAppView): c.user = self.db_user user_model = UserModel() - desc = self.request.POST.get('description') + desc = self.request.POST.get("description") try: - ip_list = user_model.parse_ip_range( - self.request.POST.get('new_ip')) + ip_list = user_model.parse_ip_range(self.request.POST.get("new_ip")) except Exception as e: ip_list = [] log.exception("Exception during ip saving") - h.flash(_('An error occurred during ip saving:%s' % (e,)), - category='error') + h.flash(_("An error occurred during ip saving:%s" % (e,)), category="error") added = [] user_data = c.user.get_api_data() for ip in ip_list: try: form = UserExtraIpForm(self.request.translate)() - data = form.to_python({'ip': ip}) - ip = data['ip'] + data = form.to_python({"ip": ip}) + ip = data["ip"] user_model.add_extra_ip(c.user.user_id, ip, desc) audit_logger.store_web( - 'user.edit.ip.add', - action_data={'ip': ip, 'user': user_data}, - user=self._rhodecode_user) + "user.edit.ip.add", action_data={"ip": ip, "user": user_data}, user=self._rhodecode_user + ) Session().commit() added.append(ip) except formencode.Invalid as error: - msg = error.unpack_errors()['ip'] - h.flash(msg, category='error') + msg = error.unpack_errors()["ip"] + h.flash(msg, category="error") except Exception: log.exception("Exception during ip saving") - h.flash(_('An error occurred during ip saving'), - category='error') + h.flash(_("An error occurred during ip saving"), category="error") if added: - h.flash( - _("Added ips %s to user whitelist") % (', '.join(ip_list), ), - category='success') - if 'default_user' in self.request.POST: + h.flash(_("Added ips %s to user whitelist") % (", ".join(ip_list),), category="success") + if "default_user" in self.request.POST: # case for editing global IP list we do it for 'DEFAULT' user - raise HTTPFound(h.route_path('admin_permissions_ips')) - raise HTTPFound(h.route_path('edit_user_ips', user_id=user_id)) + raise HTTPFound(h.route_path("admin_permissions_ips")) + raise HTTPFound(h.route_path("edit_user_ips", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() # NOTE(marcink): this view is allowed for default users, as we can # edit their IP white list @@ -1144,38 +1081,37 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - ip_id = self.request.POST.get('del_ip_id') + ip_id = self.request.POST.get("del_ip_id") user_model = UserModel() user_data = c.user.get_api_data() ip = UserIpMap.query().get(ip_id).ip_addr user_model.delete_extra_ip(c.user.user_id, ip_id) audit_logger.store_web( - 'user.edit.ip.delete', action_data={'ip': ip, 'user': user_data}, - user=self._rhodecode_user) + "user.edit.ip.delete", action_data={"ip": ip, "user": user_data}, user=self._rhodecode_user + ) Session().commit() - h.flash(_("Removed ip address from user whitelist"), category='success') + h.flash(_("Removed ip address from user whitelist"), category="success") - if 'default_user' in self.request.POST: + if "default_user" in self.request.POST: # case for editing global IP list we do it for 'DEFAULT' user - raise HTTPFound(h.route_path('admin_permissions_ips')) - raise HTTPFound(h.route_path('edit_user_ips', user_id=user_id)) + raise HTTPFound(h.route_path("admin_permissions_ips")) + raise HTTPFound(h.route_path("edit_user_ips", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def groups_management(self): c = self.load_default_context() c.user = self.db_user c.data = c.user.group_member - groups = [UserGroupModel.get_user_groups_as_dict(group.users_group) - for group in c.user.group_member] + groups = [UserGroupModel.get_user_groups_as_dict(group.users_group) for group in c.user.group_member] c.groups = ext_json.str_json(groups) - c.active = 'groups' + c.active = "groups" return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def groups_management_updates(self): _ = self.request.translate @@ -1184,69 +1120,65 @@ class UsersView(UserAppView): user_id = self.db_user_id c.user = self.db_user - user_groups = set(self.request.POST.getall('users_group_id')) + user_groups = set(self.request.POST.getall("users_group_id")) user_groups_objects = [] for ugid in user_groups: - user_groups_objects.append( - UserGroupModel().get_group(safe_int(ugid))) + user_groups_objects.append(UserGroupModel().get_group(safe_int(ugid))) user_group_model = UserGroupModel() - added_to_groups, removed_from_groups = \ - user_group_model.change_groups(c.user, user_groups_objects) + added_to_groups, removed_from_groups = user_group_model.change_groups(c.user, user_groups_objects) user_data = c.user.get_api_data() for user_group_id in added_to_groups: user_group = UserGroup.get(user_group_id) old_values = user_group.get_api_data() audit_logger.store_web( - 'user_group.edit.member.add', - action_data={'user': user_data, 'old_data': old_values}, - user=self._rhodecode_user) + "user_group.edit.member.add", + action_data={"user": user_data, "old_data": old_values}, + user=self._rhodecode_user, + ) for user_group_id in removed_from_groups: user_group = UserGroup.get(user_group_id) old_values = user_group.get_api_data() audit_logger.store_web( - 'user_group.edit.member.delete', - action_data={'user': user_data, 'old_data': old_values}, - user=self._rhodecode_user) + "user_group.edit.member.delete", + action_data={"user": user_data, "old_data": old_values}, + user=self._rhodecode_user, + ) Session().commit() - c.active = 'user_groups_management' - h.flash(_("Groups successfully changed"), category='success') + c.active = "user_groups_management" + h.flash(_("Groups successfully changed"), category="success") - return HTTPFound(h.route_path( - 'edit_user_groups_management', user_id=user_id)) + return HTTPFound(h.route_path("edit_user_groups_management", user_id=user_id)) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_audit_logs(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'audit' + c.active = "audit" - p = safe_int(self.request.GET.get('page', 1), 1) + p = safe_int(self.request.GET.get("page", 1), 1) - filter_term = self.request.GET.get('filter') + filter_term = self.request.GET.get("filter") user_log = UserModel().get_user_log(c.user, filter_term) def url_generator(page_num): - query_params = { - 'page': page_num - } + query_params = {"page": page_num} if filter_term: - query_params['filter'] = filter_term + query_params["filter"] = filter_term return self.request.current_route_path(_query=query_params) - c.audit_logs = SqlPage( - user_log, page=p, items_per_page=10, url_maker=url_generator) + c.audit_logs = SqlPage(user_log, page=p, items_per_page=10, url_maker=url_generator) c.filter_term = filter_term return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_audit_logs_download(self): _ = self.request.translate c = self.load_default_context() @@ -1259,25 +1191,25 @@ class UsersView(UserAppView): audit_log_data[entry.user_log_id] = entry.get_dict() response = Response(ext_json.formatted_str_json(audit_log_data)) - response.content_disposition = f'attachment; filename=user_{c.user.user_id}_audit_logs.json' - response.content_type = 'application/json' + response.content_disposition = f"attachment; filename=user_{c.user.user_id}_audit_logs.json" + response.content_type = "application/json" return response @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_perms_summary(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'perms_summary' + c.active = "perms_summary" c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_perms_summary_json(self): self.load_default_context() perm_user = self.db_user.AuthUser(ip_addr=self.request.remote_addr) @@ -1285,37 +1217,36 @@ class UsersView(UserAppView): return perm_user.permissions @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def user_caches(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'caches' + c.active = "caches" c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) - cache_namespace_uid = f'cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{self.db_user.user_id}' - c.region = rc_cache.get_or_create_region('cache_perms', cache_namespace_uid) + cache_namespace_uid = f"cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{self.db_user.user_id}" + c.region = rc_cache.get_or_create_region("cache_perms", cache_namespace_uid) c.backend = c.region.backend c.user_keys = sorted(c.region.backend.list_keys(prefix=cache_namespace_uid)) return self._get_template_context(c) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def user_caches_update(self): _ = self.request.translate c = self.load_default_context() c.user = self.db_user - c.active = 'caches' + c.active = "caches" c.perm_user = c.user.AuthUser(ip_addr=self.request.remote_addr) - cache_namespace_uid = f'cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{self.db_user.user_id}' - del_keys = rc_cache.clear_cache_namespace('cache_perms', cache_namespace_uid, method=rc_cache.CLEAR_DELETE) + cache_namespace_uid = f"cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{self.db_user.user_id}" + del_keys = rc_cache.clear_cache_namespace("cache_perms", cache_namespace_uid, method=rc_cache.CLEAR_DELETE) - h.flash(_("Deleted {} cache keys").format(del_keys), category='success') + h.flash(_("Deleted {} cache keys").format(del_keys), category="success") - return HTTPFound(h.route_path( - 'edit_user_caches', user_id=c.user.user_id)) + return HTTPFound(h.route_path("edit_user_caches", user_id=c.user.user_id)) diff --git a/rhodecode/apps/channelstream/__init__.py b/rhodecode/apps/channelstream/__init__.py index aab02a16..94e309d2 100644 --- a/rhodecode/apps/channelstream/__init__.py +++ b/rhodecode/apps/channelstream/__init__.py @@ -25,42 +25,39 @@ from rhodecode.apps._base import ADMIN_PREFIX from rhodecode.lib.ext_json import str_json - def url_gen(request): registry = request.registry - longpoll_url = registry.settings.get('channelstream.longpoll_url', '') - ws_url = registry.settings.get('channelstream.ws_url', '') - proxy_url = request.route_url('channelstream_proxy') + longpoll_url = registry.settings.get("channelstream.longpoll_url", "") + ws_url = registry.settings.get("channelstream.ws_url", "") + proxy_url = request.route_url("channelstream_proxy") urls = { - 'connect': request.route_path('channelstream_connect'), - 'subscribe': request.route_path('channelstream_subscribe'), - 'longpoll': longpoll_url or proxy_url, - 'ws': ws_url or proxy_url.replace('http', 'ws') + "connect": request.route_path("channelstream_connect"), + "subscribe": request.route_path("channelstream_subscribe"), + "longpoll": longpoll_url or proxy_url, + "ws": ws_url or proxy_url.replace("http", "ws"), } return str_json(urls) PLUGIN_DEFINITION = { - 'name': 'channelstream', - 'config': { - 'javascript': [], - 'css': [], - 'template_hooks': { - 'plugin_init_template': 'rhodecode:templates/channelstream/plugin_init.mako' - }, - 'url_gen': url_gen, - 'static': None, - 'enabled': False, - 'server': '', - 'secret': '' - } + "name": "channelstream", + "config": { + "javascript": [], + "css": [], + "template_hooks": {"plugin_init_template": "rhodecode:templates/channelstream/plugin_init.mako"}, + "url_gen": url_gen, + "static": None, + "enabled": False, + "server": "", + "secret": "", + }, } def maybe_create_history_store(event): # create plugin history location settings = event.app.registry.settings - history_dir = settings.get('channelstream.history.location', '') + history_dir = settings.get("channelstream.history.location", "") if history_dir and not os.path.exists(history_dir): os.makedirs(history_dir, 0o750) @@ -69,37 +66,21 @@ def includeme(config): from rhodecode.apps.channelstream.views import ChannelstreamView settings = config.registry.settings - PLUGIN_DEFINITION['config']['enabled'] = asbool( - settings.get('channelstream.enabled')) - PLUGIN_DEFINITION['config']['server'] = settings.get( - 'channelstream.server', '') - PLUGIN_DEFINITION['config']['secret'] = settings.get( - 'channelstream.secret', '') - PLUGIN_DEFINITION['config']['history.location'] = settings.get( - 'channelstream.history.location', '') - config.register_rhodecode_plugin( - PLUGIN_DEFINITION['name'], - PLUGIN_DEFINITION['config'] - ) + PLUGIN_DEFINITION["config"]["enabled"] = asbool(settings.get("channelstream.enabled")) + PLUGIN_DEFINITION["config"]["server"] = settings.get("channelstream.server", "") + PLUGIN_DEFINITION["config"]["secret"] = settings.get("channelstream.secret", "") + PLUGIN_DEFINITION["config"]["history.location"] = settings.get("channelstream.history.location", "") + config.register_rhodecode_plugin(PLUGIN_DEFINITION["name"], PLUGIN_DEFINITION["config"]) config.add_subscriber(maybe_create_history_store, ApplicationCreated) - config.add_route( - name='channelstream_connect', - pattern=ADMIN_PREFIX + '/channelstream/connect') + config.add_route(name="channelstream_connect", pattern=ADMIN_PREFIX + "/channelstream/connect") config.add_view( - ChannelstreamView, - attr='channelstream_connect', - route_name='channelstream_connect', renderer='json_ext') + ChannelstreamView, attr="channelstream_connect", route_name="channelstream_connect", renderer="json_ext" + ) - config.add_route( - name='channelstream_subscribe', - pattern=ADMIN_PREFIX + '/channelstream/subscribe') + config.add_route(name="channelstream_subscribe", pattern=ADMIN_PREFIX + "/channelstream/subscribe") config.add_view( - ChannelstreamView, - attr='channelstream_subscribe', - route_name='channelstream_subscribe', renderer='json_ext') - - config.add_route( - name='channelstream_proxy', - pattern=settings.get('channelstream.proxy_path') or '/_channelstream') + ChannelstreamView, attr="channelstream_subscribe", route_name="channelstream_subscribe", renderer="json_ext" + ) + config.add_route(name="channelstream_proxy", pattern=settings.get("channelstream.proxy_path") or "/_channelstream") diff --git a/rhodecode/apps/channelstream/views.py b/rhodecode/apps/channelstream/views.py index e6c05757..2198f249 100644 --- a/rhodecode/apps/channelstream/views.py +++ b/rhodecode/apps/channelstream/views.py @@ -24,7 +24,8 @@ from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPBadGateway from rhodecode.apps._base import BaseAppView from rhodecode.lib.channelstream import ( - channelstream_request, get_channelstream_server_url, + channelstream_request, + get_channelstream_server_url, ChannelstreamConnectionException, ChannelstreamPermissionException, check_channel_permissions, @@ -32,7 +33,8 @@ from rhodecode.lib.channelstream import ( get_user_data, parse_channels_info, update_history_from_logs, - USER_STATE_PUBLIC_KEYS) + USER_STATE_PUBLIC_KEYS, +) from rhodecode.lib.auth import NotAnonymous @@ -40,34 +42,32 @@ log = logging.getLogger(__name__) class ChannelstreamView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() - self.channelstream_config = \ - self.request.registry.rhodecode_plugins['channelstream'] - if not self.channelstream_config.get('enabled'): - log.warning('Channelstream plugin is disabled') + self.channelstream_config = self.request.registry.rhodecode_plugins["channelstream"] + if not self.channelstream_config.get("enabled"): + log.warning("Channelstream plugin is disabled") raise HTTPBadRequest() return c @NotAnonymous() def channelstream_connect(self): - """ handle authorization of users trying to connect """ + """handle authorization of users trying to connect""" self.load_default_context() try: json_body = self.request.json_body except Exception: - log.exception('Failed to decode json from request') + log.exception("Failed to decode json from request") raise HTTPBadRequest() try: channels = check_channel_permissions( - json_body.get('channels'), - get_connection_validators(self.request.registry)) + json_body.get("channels"), get_connection_validators(self.request.registry) + ) except ChannelstreamPermissionException: - log.error('Incorrect permissions for requested channels') + log.error("Incorrect permissions for requested channels") raise HTTPForbidden() user = self._rhodecode_user @@ -75,109 +75,95 @@ class ChannelstreamView(BaseAppView): user_data = get_user_data(user.user_id) else: user_data = { - 'id': None, - 'username': None, - 'first_name': None, - 'last_name': None, - 'icon_link': None, - 'display_name': None, - 'display_link': None, + "id": None, + "username": None, + "first_name": None, + "last_name": None, + "icon_link": None, + "display_name": None, + "display_link": None, } - #user_data['permissions'] = self._rhodecode_user.permissions_safe + # user_data['permissions'] = self._rhodecode_user.permissions_safe payload = { - 'username': user.username, - 'user_state': user_data, - 'conn_id': str(uuid.uuid4()), - 'channels': channels, - 'channel_configs': {}, - 'state_public_keys': USER_STATE_PUBLIC_KEYS, - 'info': { - 'exclude_channels': ['broadcast'] - } + "username": user.username, + "user_state": user_data, + "conn_id": str(uuid.uuid4()), + "channels": channels, + "channel_configs": {}, + "state_public_keys": USER_STATE_PUBLIC_KEYS, + "info": {"exclude_channels": ["broadcast"]}, } - filtered_channels = [channel for channel in channels - if channel != 'broadcast'] + filtered_channels = [channel for channel in channels if channel != "broadcast"] for channel in filtered_channels: - payload['channel_configs'][channel] = { - 'notify_presence': True, - 'history_size': 100, - 'store_history': True, - 'broadcast_presence_with_user_lists': True + payload["channel_configs"][channel] = { + "notify_presence": True, + "history_size": 100, + "store_history": True, + "broadcast_presence_with_user_lists": True, } # connect user to server - channelstream_url = get_channelstream_server_url( - self.channelstream_config, '/connect') + channelstream_url = get_channelstream_server_url(self.channelstream_config, "/connect") try: - connect_result = channelstream_request( - self.channelstream_config, payload, '/connect') + connect_result = channelstream_request(self.channelstream_config, payload, "/connect") except ChannelstreamConnectionException: - log.exception( - f'Channelstream service at {channelstream_url} is down') + log.exception(f"Channelstream service at {channelstream_url} is down") return HTTPBadGateway() - channel_info = connect_result.get('channels_info') + channel_info = connect_result.get("channels_info") if not channel_info: raise HTTPBadRequest() - connect_result['channels'] = channels - connect_result['channels_info'] = parse_channels_info( - channel_info, include_channel_info=filtered_channels) - update_history_from_logs(self.channelstream_config, - filtered_channels, connect_result) + connect_result["channels"] = channels + connect_result["channels_info"] = parse_channels_info(channel_info, include_channel_info=filtered_channels) + update_history_from_logs(self.channelstream_config, filtered_channels, connect_result) return connect_result @NotAnonymous() def channelstream_subscribe(self): - """ can be used to subscribe specific connection to other channels """ + """can be used to subscribe specific connection to other channels""" self.load_default_context() try: json_body = self.request.json_body except Exception: - log.exception('Failed to decode json from request') + log.exception("Failed to decode json from request") raise HTTPBadRequest() try: channels = check_channel_permissions( - json_body.get('channels'), - get_connection_validators(self.request.registry)) + json_body.get("channels"), get_connection_validators(self.request.registry) + ) except ChannelstreamPermissionException: - log.error('Incorrect permissions for requested channels') + log.error("Incorrect permissions for requested channels") raise HTTPForbidden() - payload = {'conn_id': json_body.get('conn_id', ''), - 'channels': channels, - 'channel_configs': {}, - 'info': { - 'exclude_channels': ['broadcast']} - } - filtered_channels = [chan for chan in channels if chan != 'broadcast'] + payload = { + "conn_id": json_body.get("conn_id", ""), + "channels": channels, + "channel_configs": {}, + "info": {"exclude_channels": ["broadcast"]}, + } + filtered_channels = [chan for chan in channels if chan != "broadcast"] for channel in filtered_channels: - payload['channel_configs'][channel] = { - 'notify_presence': True, - 'history_size': 100, - 'store_history': True, - 'broadcast_presence_with_user_lists': True + payload["channel_configs"][channel] = { + "notify_presence": True, + "history_size": 100, + "store_history": True, + "broadcast_presence_with_user_lists": True, } - channelstream_url = get_channelstream_server_url( - self.channelstream_config, '/subscribe') + channelstream_url = get_channelstream_server_url(self.channelstream_config, "/subscribe") try: - connect_result = channelstream_request( - self.channelstream_config, payload, '/subscribe') + connect_result = channelstream_request(self.channelstream_config, payload, "/subscribe") except ChannelstreamConnectionException: - log.exception( - f'Channelstream service at {channelstream_url} is down') + log.exception(f"Channelstream service at {channelstream_url} is down") return HTTPBadGateway() - channel_info = connect_result.get('channels_info') + channel_info = connect_result.get("channels_info") if not channel_info: raise HTTPBadRequest() # include_channel_info will limit history only to new channel # to not overwrite histories on other channels in client - connect_result['channels_info'] = parse_channels_info( - channel_info, - include_channel_info=filtered_channels) - update_history_from_logs( - self.channelstream_config, filtered_channels, connect_result) + connect_result["channels_info"] = parse_channels_info(channel_info, include_channel_info=filtered_channels) + update_history_from_logs(self.channelstream_config, filtered_channels, connect_result) return connect_result diff --git a/rhodecode/apps/debug_style/__init__.py b/rhodecode/apps/debug_style/__init__.py index a844ba57..6955c0a4 100644 --- a/rhodecode/apps/debug_style/__init__.py +++ b/rhodecode/apps/debug_style/__init__.py @@ -24,56 +24,41 @@ class DebugStylePredicate(object): self.val = val def text(self): - return f'debug style route = {self.val}' + return f"debug style route = {self.val}" phash = text def __call__(self, info, request): - return str2bool(request.registry.settings.get('debug_style')) + return str2bool(request.registry.settings.get("debug_style")) def includeme(config): from rhodecode.apps.debug_style.views import DebugStyleView - config.add_route_predicate( - 'debug_style', DebugStylePredicate) + config.add_route_predicate("debug_style", DebugStylePredicate) + + config.add_route(name="debug_style_home", pattern=ADMIN_PREFIX + "/debug_style", debug_style=True) + config.add_view(DebugStyleView, attr="index", route_name="debug_style_home", request_method="GET", renderer=None) + + config.add_route(name="debug_style_email", pattern=ADMIN_PREFIX + "/debug_style/email/{email_id}", debug_style=True) + config.add_view( + DebugStyleView, attr="render_email", route_name="debug_style_email", request_method="GET", renderer=None + ) config.add_route( - name='debug_style_home', - pattern=ADMIN_PREFIX + '/debug_style', - debug_style=True) + name="debug_style_email_plain_rendered", + pattern=ADMIN_PREFIX + "/debug_style/email-rendered/{email_id}", + debug_style=True, + ) config.add_view( DebugStyleView, - attr='index', - route_name='debug_style_home', request_method='GET', - renderer=None) + attr="render_email", + route_name="debug_style_email_plain_rendered", + request_method="GET", + renderer=None, + ) - config.add_route( - name='debug_style_email', - pattern=ADMIN_PREFIX + '/debug_style/email/{email_id}', - debug_style=True) + config.add_route(name="debug_style_template", pattern=ADMIN_PREFIX + "/debug_style/t/{t_path}", debug_style=True) config.add_view( - DebugStyleView, - attr='render_email', - route_name='debug_style_email', request_method='GET', - renderer=None) - - config.add_route( - name='debug_style_email_plain_rendered', - pattern=ADMIN_PREFIX + '/debug_style/email-rendered/{email_id}', - debug_style=True) - config.add_view( - DebugStyleView, - attr='render_email', - route_name='debug_style_email_plain_rendered', request_method='GET', - renderer=None) - - config.add_route( - name='debug_style_template', - pattern=ADMIN_PREFIX + '/debug_style/t/{t_path}', - debug_style=True) - config.add_view( - DebugStyleView, - attr='template', - route_name='debug_style_template', request_method='GET', - renderer=None) + DebugStyleView, attr="template", route_name="debug_style_template", request_method="GET", renderer=None + ) diff --git a/rhodecode/apps/debug_style/views.py b/rhodecode/apps/debug_style/views.py index ad131a9f..20205825 100644 --- a/rhodecode/apps/debug_style/views.py +++ b/rhodecode/apps/debug_style/views.py @@ -31,162 +31,138 @@ log = logging.getLogger(__name__) class DebugStyleView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c def index(self): c = self.load_default_context() - c.active = 'index' + c.active = "index" - return render_to_response( - 'debug_style/index.html', self._get_template_context(c), - request=self.request) + return render_to_response("debug_style/index.html", self._get_template_context(c), request=self.request) def render_email(self): c = self.load_default_context() - email_id = self.request.matchdict['email_id'] - c.active = 'emails' + email_id = self.request.matchdict["email_id"] + c.active = "emails" pr = AttributeDict( pull_request_id=123, - title='digital_ocean: fix redis, elastic search start on boot, ' - 'fix fd limits on supervisor, set postgres 11 version', - description=''' + title="digital_ocean: fix redis, elastic search start on boot, " + "fix fd limits on supervisor, set postgres 11 version", + description=""" Check if we should use full-topic or mini-topic. - full topic produces some problems with merge states etc - server-mini-topic needs probably tweeks. - ''', - repo_name='foobar', - source_ref_parts=AttributeDict(type='branch', name='fix-ticket-2000'), - target_ref_parts=AttributeDict(type='branch', name='master'), + """, + repo_name="foobar", + source_ref_parts=AttributeDict(type="branch", name="fix-ticket-2000"), + target_ref_parts=AttributeDict(type="branch", name="master"), ) - target_repo = AttributeDict(repo_name='repo_group/target_repo') - source_repo = AttributeDict(repo_name='repo_group/source_repo') - user = User.get_by_username(self.request.GET.get('user')) or self._rhodecode_db_user + target_repo = AttributeDict(repo_name="repo_group/target_repo") + source_repo = AttributeDict(repo_name="repo_group/source_repo") + user = User.get_by_username(self.request.GET.get("user")) or self._rhodecode_db_user # file/commit changes for PR update - commit_changes = AttributeDict({ - 'added': ['aaaaaaabbbbb', 'cccccccddddddd'], - 'removed': ['eeeeeeeeeee'], - }) + commit_changes = AttributeDict( + { + "added": ["aaaaaaabbbbb", "cccccccddddddd"], + "removed": ["eeeeeeeeeee"], + } + ) - file_changes = AttributeDict({ - 'added': ['a/file1.md', 'file2.py'], - 'modified': ['b/modified_file.rst'], - 'removed': ['.idea'], - }) + file_changes = AttributeDict( + { + "added": ["a/file1.md", "file2.py"], + "modified": ["b/modified_file.rst"], + "removed": [".idea"], + } + ) exc_traceback = { - 'exc_utc_date': '2020-03-26T12:54:50.683281', - 'exc_id': 139638856342656, - 'exc_timestamp': '1585227290.683288', - 'version': 'v1', - 'exc_message': 'Traceback (most recent call last):\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/tweens.py", line 41, in excview_tween\n response = handler(request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/router.py", line 148, in handle_request\n registry, request, context, context_iface, view_name\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/view.py", line 667, in _call_view\n response = view_callable(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/config/views.py", line 188, in attr_view\n return view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/config/views.py", line 214, in predicate_wrapper\n return view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/viewderivers.py", line 401, in viewresult_to_response\n result = view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/viewderivers.py", line 132, in _class_view\n response = getattr(inst, attr)()\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/apps/debug_style/views.py", line 355, in render_email\n template_type, **email_kwargs.get(email_id, {}))\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/model/notification.py", line 402, in render_email\n body = email_template.render(None, **_kwargs)\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/lib/partial_renderer.py", line 95, in render\n return self._render_with_exc(tmpl, args, kwargs)\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/lib/partial_renderer.py", line 79, in _render_with_exc\n return render_func.render(*args, **kwargs)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/template.py", line 476, in render\n return runtime._render(self, self.callable_, args, data)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 883, in _render\n **_kwargs_for_callable(callable_, data)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 920, in _render_context\n _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 947, in _exec_template\n callable_(context, *args, **kwargs)\n File "rhodecode_templates_email_templates_base_mako", line 63, in render_body\n File "rhodecode_templates_email_templates_exception_tracker_mako", line 43, in render_body\nAttributeError: \'str\' object has no attribute \'get\'\n', - 'exc_type': 'AttributeError' + "exc_utc_date": "2020-03-26T12:54:50.683281", + "exc_id": 139638856342656, + "exc_timestamp": "1585227290.683288", + "version": "v1", + "exc_message": 'Traceback (most recent call last):\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/tweens.py", line 41, in excview_tween\n response = handler(request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/router.py", line 148, in handle_request\n registry, request, context, context_iface, view_name\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/view.py", line 667, in _call_view\n response = view_callable(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/config/views.py", line 188, in attr_view\n return view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/config/views.py", line 214, in predicate_wrapper\n return view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/viewderivers.py", line 401, in viewresult_to_response\n result = view(context, request)\n File "/nix/store/s43k2r9rysfbzmsjdqnxgzvvb7zjhkxb-python2.7-pyramid-1.10.4/lib/python2.7/site-packages/pyramid/viewderivers.py", line 132, in _class_view\n response = getattr(inst, attr)()\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/apps/debug_style/views.py", line 355, in render_email\n template_type, **email_kwargs.get(email_id, {}))\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/model/notification.py", line 402, in render_email\n body = email_template.render(None, **_kwargs)\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/lib/partial_renderer.py", line 95, in render\n return self._render_with_exc(tmpl, args, kwargs)\n File "/mnt/hgfs/marcink/workspace/rhodecode-enterprise-ce/rhodecode/lib/partial_renderer.py", line 79, in _render_with_exc\n return render_func.render(*args, **kwargs)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/template.py", line 476, in render\n return runtime._render(self, self.callable_, args, data)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 883, in _render\n **_kwargs_for_callable(callable_, data)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 920, in _render_context\n _exec_template(inherit, lclcontext, args=args, kwargs=kwargs)\n File "/nix/store/dakh34sxz4yfr435c0cwjz0sd6hnd5g3-python2.7-mako-1.1.0/lib/python2.7/site-packages/mako/runtime.py", line 947, in _exec_template\n callable_(context, *args, **kwargs)\n File "rhodecode_templates_email_templates_base_mako", line 63, in render_body\n File "rhodecode_templates_email_templates_exception_tracker_mako", line 43, in render_body\nAttributeError: \'str\' object has no attribute \'get\'\n', + "exc_type": "AttributeError", } email_kwargs = { - 'test': {}, - - 'message': { - 'body': 'message body !' + "test": {}, + "message": {"body": "message body !"}, + "email_test": { + "user": user, + "date": datetime.datetime.now(), }, - - 'email_test': { - 'user': user, - 'date': datetime.datetime.now(), + "update_available": { + "current_ver": "4.23.0", + "latest_ver": "4.24.0", }, - - 'update_available': { - 'current_ver': '4.23.0', - 'latest_ver': '4.24.0', + "exception": { + "email_prefix": "[RHODECODE ERROR]", + "exc_id": exc_traceback["exc_id"], + "exc_url": "http://server-url/{}".format(exc_traceback["exc_id"]), + "exc_type_name": "NameError", + "exc_traceback": exc_traceback, }, - - 'exception': { - 'email_prefix': '[RHODECODE ERROR]', - 'exc_id': exc_traceback['exc_id'], - 'exc_url': 'http://server-url/{}'.format(exc_traceback['exc_id']), - 'exc_type_name': 'NameError', - 'exc_traceback': exc_traceback, + "password_reset": { + "password_reset_url": "http://example.com/reset-rhodecode-password/token", + "user": user, + "date": datetime.datetime.now(), + "email": "test@rhodecode.com", + "first_admin_email": User.get_first_super_admin().email, }, - - 'password_reset': { - 'password_reset_url': 'http://example.com/reset-rhodecode-password/token', - - 'user': user, - 'date': datetime.datetime.now(), - 'email': 'test@rhodecode.com', - 'first_admin_email': User.get_first_super_admin().email + "password_reset_confirmation": { + "new_password": "new-password-example", + "user": user, + "date": datetime.datetime.now(), + "email": "test@rhodecode.com", + "first_admin_email": User.get_first_super_admin().email, }, - - 'password_reset_confirmation': { - 'new_password': 'new-password-example', - 'user': user, - 'date': datetime.datetime.now(), - 'email': 'test@rhodecode.com', - 'first_admin_email': User.get_first_super_admin().email + "registration": { + "user": user, + "date": datetime.datetime.now(), }, - - 'registration': { - 'user': user, - 'date': datetime.datetime.now(), + "pull_request_comment": { + "user": user, + "status_change": None, + "status_change_type": None, + "pull_request": pr, + "pull_request_commits": [], + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "http://target-repo/url", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "http://source-repo/url", + "pull_request_url": "http://localhost/pr1", + "pr_comment_url": "http://comment-url", + "pr_comment_reply_url": "http://comment-url#reply", + "comment_file": None, + "comment_line": None, + "comment_type": "note", + "comment_body": "This is my comment body. *I like !*", + "comment_id": 2048, + "renderer_type": "markdown", + "mention": True, }, - - 'pull_request_comment': { - 'user': user, - - 'status_change': None, - 'status_change_type': None, - - 'pull_request': pr, - 'pull_request_commits': [], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'http://target-repo/url', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'http://source-repo/url', - - 'pull_request_url': 'http://localhost/pr1', - 'pr_comment_url': 'http://comment-url', - 'pr_comment_reply_url': 'http://comment-url#reply', - - 'comment_file': None, - 'comment_line': None, - 'comment_type': 'note', - 'comment_body': 'This is my comment body. *I like !*', - 'comment_id': 2048, - 'renderer_type': 'markdown', - 'mention': True, - - }, - - 'pull_request_comment+status': { - 'user': user, - - 'status_change': 'approved', - 'status_change_type': 'approved', - - 'pull_request': pr, - 'pull_request_commits': [], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'http://target-repo/url', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'http://source-repo/url', - - 'pull_request_url': 'http://localhost/pr1', - 'pr_comment_url': 'http://comment-url', - 'pr_comment_reply_url': 'http://comment-url#reply', - - 'comment_type': 'todo', - 'comment_file': None, - 'comment_line': None, - 'comment_body': ''' + "pull_request_comment+status": { + "user": user, + "status_change": "approved", + "status_change_type": "approved", + "pull_request": pr, + "pull_request_commits": [], + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "http://target-repo/url", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "http://source-repo/url", + "pull_request_url": "http://localhost/pr1", + "pr_comment_url": "http://comment-url", + "pr_comment_reply_url": "http://comment-url#reply", + "comment_type": "todo", + "comment_file": None, + "comment_line": None, + "comment_body": """ I think something like this would be better ```py @@ -198,37 +174,28 @@ def db(): ``` - ''', - 'comment_id': 2048, - 'renderer_type': 'markdown', - 'mention': True, - + """, + "comment_id": 2048, + "renderer_type": "markdown", + "mention": True, }, - - 'pull_request_comment+file': { - 'user': user, - - 'status_change': None, - 'status_change_type': None, - - 'pull_request': pr, - 'pull_request_commits': [], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'http://target-repo/url', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'http://source-repo/url', - - 'pull_request_url': 'http://localhost/pr1', - - 'pr_comment_url': 'http://comment-url', - 'pr_comment_reply_url': 'http://comment-url#reply', - - 'comment_file': 'rhodecode/model/get_flow_commits', - 'comment_line': 'o1210', - 'comment_type': 'todo', - 'comment_body': ''' + "pull_request_comment+file": { + "user": user, + "status_change": None, + "status_change_type": None, + "pull_request": pr, + "pull_request_commits": [], + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "http://target-repo/url", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "http://source-repo/url", + "pull_request_url": "http://localhost/pr1", + "pr_comment_url": "http://comment-url", + "pr_comment_reply_url": "http://comment-url#reply", + "comment_file": "rhodecode/model/get_flow_commits", + "comment_line": "o1210", + "comment_type": "todo", + "comment_body": """ I like this ! But please check this code @@ -253,222 +220,205 @@ But please check this code }; This should work better ! - ''', - 'comment_id': 2048, - 'renderer_type': 'rst', - 'mention': True, - + """, + "comment_id": 2048, + "renderer_type": "rst", + "mention": True, }, - - 'pull_request_update': { - 'updating_user': user, - - 'status_change': None, - 'status_change_type': None, - - 'pull_request': pr, - 'pull_request_commits': [], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'http://target-repo/url', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'http://source-repo/url', - - 'pull_request_url': 'http://localhost/pr1', - + "pull_request_update": { + "updating_user": user, + "status_change": None, + "status_change_type": None, + "pull_request": pr, + "pull_request_commits": [], + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "http://target-repo/url", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "http://source-repo/url", + "pull_request_url": "http://localhost/pr1", # update comment links - 'pr_comment_url': 'http://comment-url', - 'pr_comment_reply_url': 'http://comment-url#reply', - 'ancestor_commit_id': 'f39bd443', - 'added_commits': commit_changes.added, - 'removed_commits': commit_changes.removed, - 'changed_files': (file_changes.added + file_changes.modified + file_changes.removed), - 'added_files': file_changes.added, - 'modified_files': file_changes.modified, - 'removed_files': file_changes.removed, + "pr_comment_url": "http://comment-url", + "pr_comment_reply_url": "http://comment-url#reply", + "ancestor_commit_id": "f39bd443", + "added_commits": commit_changes.added, + "removed_commits": commit_changes.removed, + "changed_files": (file_changes.added + file_changes.modified + file_changes.removed), + "added_files": file_changes.added, + "modified_files": file_changes.modified, + "removed_files": file_changes.removed, }, - - 'cs_comment': { - 'user': user, - 'commit': AttributeDict(idx=123, raw_id='a'*40, message='Commit message'), - 'status_change': None, - 'status_change_type': None, - - 'commit_target_repo_url': 'http://foo.example.com/#comment1', - 'repo_name': 'test-repo', - 'comment_type': 'note', - 'comment_file': None, - 'comment_line': None, - 'commit_comment_url': 'http://comment-url', - 'commit_comment_reply_url': 'http://comment-url#reply', - 'comment_body': 'This is my comment body. *I like !*', - 'comment_id': 2048, - 'renderer_type': 'markdown', - 'mention': True, + "cs_comment": { + "user": user, + "commit": AttributeDict(idx=123, raw_id="a" * 40, message="Commit message"), + "status_change": None, + "status_change_type": None, + "commit_target_repo_url": "http://foo.example.com/#comment1", + "repo_name": "test-repo", + "comment_type": "note", + "comment_file": None, + "comment_line": None, + "commit_comment_url": "http://comment-url", + "commit_comment_reply_url": "http://comment-url#reply", + "comment_body": "This is my comment body. *I like !*", + "comment_id": 2048, + "renderer_type": "markdown", + "mention": True, }, - - 'cs_comment+status': { - 'user': user, - 'commit': AttributeDict(idx=123, raw_id='a' * 40, message='Commit message'), - 'status_change': 'approved', - 'status_change_type': 'approved', - - 'commit_target_repo_url': 'http://foo.example.com/#comment1', - 'repo_name': 'test-repo', - 'comment_type': 'note', - 'comment_file': None, - 'comment_line': None, - 'commit_comment_url': 'http://comment-url', - 'commit_comment_reply_url': 'http://comment-url#reply', - 'comment_body': ''' + "cs_comment+status": { + "user": user, + "commit": AttributeDict(idx=123, raw_id="a" * 40, message="Commit message"), + "status_change": "approved", + "status_change_type": "approved", + "commit_target_repo_url": "http://foo.example.com/#comment1", + "repo_name": "test-repo", + "comment_type": "note", + "comment_file": None, + "comment_line": None, + "commit_comment_url": "http://comment-url", + "commit_comment_reply_url": "http://comment-url#reply", + "comment_body": """ Hello **world** This is a multiline comment :) - list - list2 - ''', - 'comment_id': 2048, - 'renderer_type': 'markdown', - 'mention': True, + """, + "comment_id": 2048, + "renderer_type": "markdown", + "mention": True, }, - - 'cs_comment+file': { - 'user': user, - 'commit': AttributeDict(idx=123, raw_id='a' * 40, message='Commit message'), - 'status_change': None, - 'status_change_type': None, - - 'commit_target_repo_url': 'http://foo.example.com/#comment1', - 'repo_name': 'test-repo', - - 'comment_type': 'note', - 'comment_file': 'test-file.py', - 'comment_line': 'n100', - - 'commit_comment_url': 'http://comment-url', - 'commit_comment_reply_url': 'http://comment-url#reply', - 'comment_body': 'This is my comment body. *I like !*', - 'comment_id': 2048, - 'renderer_type': 'markdown', - 'mention': True, + "cs_comment+file": { + "user": user, + "commit": AttributeDict(idx=123, raw_id="a" * 40, message="Commit message"), + "status_change": None, + "status_change_type": None, + "commit_target_repo_url": "http://foo.example.com/#comment1", + "repo_name": "test-repo", + "comment_type": "note", + "comment_file": "test-file.py", + "comment_line": "n100", + "commit_comment_url": "http://comment-url", + "commit_comment_reply_url": "http://comment-url#reply", + "comment_body": "This is my comment body. *I like !*", + "comment_id": 2048, + "renderer_type": "markdown", + "mention": True, }, - - 'pull_request': { - 'user': user, - 'pull_request': pr, - 'pull_request_commits': [ - ('472d1df03bf7206e278fcedc6ac92b46b01c4e21', '''\ + "pull_request": { + "user": user, + "pull_request": pr, + "pull_request_commits": [ + ( + "472d1df03bf7206e278fcedc6ac92b46b01c4e21", + """\ my-account: moved email closer to profile as it's similar data just moved outside. - '''), - ('cbfa3061b6de2696c7161ed15ba5c6a0045f90a7', '''\ + """, + ), + ( + "cbfa3061b6de2696c7161ed15ba5c6a0045f90a7", + """\ users: description edit fixes - tests - added metatags info - '''), + """, + ), ], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'http://target-repo/url', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'http://source-repo/url', - - 'pull_request_url': 'http://code.rhodecode.com/_pull-request/123', - 'user_role': 'reviewer', + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "http://target-repo/url", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "http://source-repo/url", + "pull_request_url": "http://code.rhodecode.com/_pull-request/123", + "user_role": "reviewer", }, - - 'pull_request+reviewer_role': { - 'user': user, - 'pull_request': pr, - 'pull_request_commits': [ - ('472d1df03bf7206e278fcedc6ac92b46b01c4e21', '''\ + "pull_request+reviewer_role": { + "user": user, + "pull_request": pr, + "pull_request_commits": [ + ( + "472d1df03bf7206e278fcedc6ac92b46b01c4e21", + """\ my-account: moved email closer to profile as it's similar data just moved outside. - '''), - ('cbfa3061b6de2696c7161ed15ba5c6a0045f90a7', '''\ + """, + ), + ( + "cbfa3061b6de2696c7161ed15ba5c6a0045f90a7", + """\ users: description edit fixes - tests - added metatags info - '''), + """, + ), ], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'http://target-repo/url', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'http://source-repo/url', - - 'pull_request_url': 'http://code.rhodecode.com/_pull-request/123', - 'user_role': 'reviewer', + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "http://target-repo/url", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "http://source-repo/url", + "pull_request_url": "http://code.rhodecode.com/_pull-request/123", + "user_role": "reviewer", }, - - 'pull_request+observer_role': { - 'user': user, - 'pull_request': pr, - 'pull_request_commits': [ - ('472d1df03bf7206e278fcedc6ac92b46b01c4e21', '''\ + "pull_request+observer_role": { + "user": user, + "pull_request": pr, + "pull_request_commits": [ + ( + "472d1df03bf7206e278fcedc6ac92b46b01c4e21", + """\ my-account: moved email closer to profile as it's similar data just moved outside. - '''), - ('cbfa3061b6de2696c7161ed15ba5c6a0045f90a7', '''\ + """, + ), + ( + "cbfa3061b6de2696c7161ed15ba5c6a0045f90a7", + """\ users: description edit fixes - tests - added metatags info - '''), + """, + ), ], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'http://target-repo/url', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'http://source-repo/url', - - 'pull_request_url': 'http://code.rhodecode.com/_pull-request/123', - 'user_role': 'observer' - } + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "http://target-repo/url", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "http://source-repo/url", + "pull_request_url": "http://code.rhodecode.com/_pull-request/123", + "user_role": "observer", + }, } - template_type = email_id.split('+')[0] + template_type = email_id.split("+")[0] (c.subject, c.email_body, c.email_body_plaintext) = EmailNotificationModel().render_email( - template_type, **email_kwargs.get(email_id, {})) + template_type, **email_kwargs.get(email_id, {}) + ) - test_email = self.request.GET.get('email') + test_email = self.request.GET.get("email") if test_email: recipients = [test_email] - run_task(tasks.send_email, recipients, c.subject, - c.email_body_plaintext, c.email_body) + run_task(tasks.send_email, recipients, c.subject, c.email_body_plaintext, c.email_body) - if self.request.matched_route.name == 'debug_style_email_plain_rendered': - template = 'debug_style/email_plain_rendered.mako' + if self.request.matched_route.name == "debug_style_email_plain_rendered": + template = "debug_style/email_plain_rendered.mako" else: - template = 'debug_style/email.mako' - return render_to_response( - template, self._get_template_context(c), - request=self.request) + template = "debug_style/email.mako" + return render_to_response(template, self._get_template_context(c), request=self.request) def template(self): - t_path = self.request.matchdict['t_path'] + t_path = self.request.matchdict["t_path"] c = self.load_default_context() c.active = os.path.splitext(t_path)[0] - c.came_from = '' + c.came_from = "" # NOTE(marcink): extend the email types with variations based on data sets c.email_types = { - 'cs_comment+file': {}, - 'cs_comment+status': {}, - - 'pull_request_comment+file': {}, - 'pull_request_comment+status': {}, - - 'pull_request_update': {}, - - 'pull_request+reviewer_role': {}, - 'pull_request+observer_role': {}, + "cs_comment+file": {}, + "cs_comment+status": {}, + "pull_request_comment+file": {}, + "pull_request_comment+status": {}, + "pull_request_update": {}, + "pull_request+reviewer_role": {}, + "pull_request+observer_role": {}, } c.email_types.update(EmailNotificationModel.email_types) - return render_to_response( - 'debug_style/' + t_path, self._get_template_context(c), - request=self.request) + return render_to_response("debug_style/" + t_path, self._get_template_context(c), request=self.request) diff --git a/rhodecode/apps/file_store/__init__.py b/rhodecode/apps/file_store/__init__.py index f0986bce..cd9f1c86 100755 --- a/rhodecode/apps/file_store/__init__.py +++ b/rhodecode/apps/file_store/__init__.py @@ -40,58 +40,52 @@ def _sanitize_settings_and_apply_defaults(settings): settings_maker = SettingsMaker(settings) - default_cache_dir = settings['cache_dir'] - default_store_dir = os.path.join(default_cache_dir, 'artifacts_filestore') + default_cache_dir = settings["cache_dir"] + default_store_dir = os.path.join(default_cache_dir, "artifacts_filestore") # set default backend settings_maker.make_setting(config_keys.backend_type, config_keys.backend_legacy_filesystem) # legacy filesystem defaults - settings_maker.make_setting(config_keys.legacy_filesystem_storage_path, default_store_dir, default_when_empty=True, ) + settings_maker.make_setting( + config_keys.legacy_filesystem_storage_path, + default_store_dir, + default_when_empty=True, + ) # filesystem defaults - settings_maker.make_setting(config_keys.filesystem_storage_path, default_store_dir, default_when_empty=True,) - settings_maker.make_setting(config_keys.filesystem_shards, 8, parser='int') + settings_maker.make_setting( + config_keys.filesystem_storage_path, + default_store_dir, + default_when_empty=True, + ) + settings_maker.make_setting(config_keys.filesystem_shards, 8, parser="int") # objectstore defaults - settings_maker.make_setting(config_keys.objectstore_url, 'http://s3-minio:9000') - settings_maker.make_setting(config_keys.objectstore_bucket, 'rhodecode-artifacts-filestore') - settings_maker.make_setting(config_keys.objectstore_bucket_shards, 8, parser='int') + settings_maker.make_setting(config_keys.objectstore_url, "http://s3-minio:9000") + settings_maker.make_setting(config_keys.objectstore_bucket, "rhodecode-artifacts-filestore") + settings_maker.make_setting(config_keys.objectstore_bucket_shards, 8, parser="int") - settings_maker.make_setting(config_keys.objectstore_region, '') - settings_maker.make_setting(config_keys.objectstore_key, '') - settings_maker.make_setting(config_keys.objectstore_secret, '') + settings_maker.make_setting(config_keys.objectstore_region, "") + settings_maker.make_setting(config_keys.objectstore_key, "") + settings_maker.make_setting(config_keys.objectstore_secret, "") settings_maker.env_expand() def includeme(config): - from rhodecode.apps.file_store.views import FileStoreView settings = config.registry.settings _sanitize_settings_and_apply_defaults(settings) - config.add_route( - name='upload_file', - pattern='/_file_store/upload') + config.add_route(name="upload_file", pattern="/_file_store/upload") config.add_view( - FileStoreView, - attr='upload_file', - route_name='upload_file', request_method='POST', renderer='json_ext') + FileStoreView, attr="upload_file", route_name="upload_file", request_method="POST", renderer="json_ext" + ) - config.add_route( - name='download_file', - pattern='/_file_store/download/{fid:.*}') - config.add_view( - FileStoreView, - attr='download_file', - route_name='download_file') + config.add_route(name="download_file", pattern="/_file_store/download/{fid:.*}") + config.add_view(FileStoreView, attr="download_file", route_name="download_file") - config.add_route( - name='download_file_by_token', - pattern='/_file_store/token-download/{_auth_token}/{fid:.*}') - config.add_view( - FileStoreView, - attr='download_file_by_token', - route_name='download_file_by_token') + config.add_route(name="download_file_by_token", pattern="/_file_store/token-download/{_auth_token}/{fid:.*}") + config.add_view(FileStoreView, attr="download_file_by_token", route_name="download_file_by_token") diff --git a/rhodecode/apps/file_store/backends/base.py b/rhodecode/apps/file_store/backends/base.py index 05e66827..09539cd5 100644 --- a/rhodecode/apps/file_store/backends/base.py +++ b/rhodecode/apps/file_store/backends/base.py @@ -30,9 +30,8 @@ log = logging.getLogger(__name__) class BaseShard: - - metadata_suffix: str = '.metadata' - storage_type: str = '' + metadata_suffix: str = ".metadata" + storage_type: str = "" fs = None @property @@ -49,7 +48,7 @@ class BaseShard: return metadata def get_metadata_filename(self, uid_filename) -> tuple[str, str]: - metadata_file: str = f'{uid_filename}{self.metadata_suffix}' + metadata_file: str = f"{uid_filename}{self.metadata_suffix}" return metadata_file, self.store_path(metadata_file) def get_metadata(self, uid_filename, ignore_missing=False) -> dict: @@ -57,16 +56,32 @@ class BaseShard: if ignore_missing and not self.fs.exists(metadata_file_path): return {} - with self.fs.open(metadata_file_path, 'rb') as f: + with self.fs.open(metadata_file_path, "rb") as f: metadata = json.loads(f.read()) metadata = self.metadata_convert(uid_filename, metadata) return metadata - def _store(self, key: str, uid_key: str, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs): + def _store( + self, + key: str, + uid_key: str, + value_reader, + max_filesize: int | None = None, + metadata: dict | None = None, + **kwargs, + ): raise NotImplementedError - def store(self, key: str, uid_key: str, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs): + def store( + self, + key: str, + uid_key: str, + value_reader, + max_filesize: int | None = None, + metadata: dict | None = None, + **kwargs, + ): return self._store(key, uid_key, value_reader, max_filesize, metadata, **kwargs) def _fetch(self, key, presigned_url_expires: int = 0): @@ -77,12 +92,12 @@ class BaseShard: def _delete(self, key): if key not in self: - log.exception(f'requested key={key} not found in {self}') + log.exception(f"requested key={key} not found in {self}") raise KeyError(key) metadata = self.get_metadata(key) _metadata_file, metadata_file_path = self.get_metadata_filename(key) - artifact_file_path = metadata['filename_uid_path'] + artifact_file_path = metadata["filename_uid_path"] self.fs.rm(artifact_file_path) self.fs.rm(metadata_file_path) @@ -99,18 +114,18 @@ class BaseFileStoreBackend: _shards = tuple() _shard_cls = BaseShard _config: dict | None = None - _storage_path: str = '' + _storage_path: str = "" def __init__(self, settings, extension_groups=None): self._config = settings - extension_groups = extension_groups or ['any'] + extension_groups = extension_groups or ["any"] self.extensions = resolve_extensions([], groups=extension_groups) def __contains__(self, key): return self.filename_exists(key) def __repr__(self): - return f'<{self.__class__.__name__}(storage={self.storage_path})>' + return f"<{self.__class__.__name__}(storage={self.storage_path})>" @property def storage_path(self): @@ -125,7 +140,7 @@ class BaseFileStoreBackend: hash_int = int(hash_value, 16) # Map the hash integer to a shard number between 1 and num_shards - shard_number = (hash_int % num_shards) + shard_number = hash_int % num_shards return shard_number @@ -138,7 +153,7 @@ class BaseFileStoreBackend: :param filename: The original filename. :return: The modified filename with the counter. """ - name_counted = f'{counter:d}-{filename}' + name_counted = f"{counter:d}-{filename}" return name_counted def _get_shard(self, key) -> _shard_cls: @@ -148,8 +163,7 @@ class BaseFileStoreBackend: def get_conf(self, key, pop=False): if key not in self._config: - raise ValueError( - f"No configuration key '{key}', please make sure it exists in filestore config") + raise ValueError(f"No configuration key '{key}', please make sure it exists in filestore config") val = self._config[key] if pop: del self._config[key] @@ -172,8 +186,9 @@ class BaseFileStoreBackend: :param ext: extension to check :param extensions: iterable of extensions to validate against (or self.extensions) """ + def normalize_ext(_ext): - if _ext.startswith('.'): + if _ext.startswith("."): _ext = _ext[1:] return _ext.lower() @@ -200,11 +215,13 @@ class BaseFileStoreBackend: shard = self._get_shard(uid_filename) return shard.get_metadata_filename(uid_filename) - def store(self, filename, value_reader, extensions=None, metadata=None, max_filesize=None, randomized_name=True, **kwargs): + def store( + self, filename, value_reader, extensions=None, metadata=None, max_filesize=None, randomized_name=True, **kwargs + ): extensions = extensions or self.extensions if not self.filename_allowed(filename, extensions): - msg = f'filename {filename} does not allow extensions {extensions}' + msg = f"filename {filename} does not allow extensions {extensions}" raise FileNotAllowedException(msg) # # TODO: check why we need this setting ? it looks stupid... @@ -215,7 +232,7 @@ class BaseFileStoreBackend: # else: # value_reader.seek(0) - uid_filename = kwargs.pop('uid_filename', None) + uid_filename = kwargs.pop("uid_filename", None) if uid_filename is None: uid_filename = get_uid_filename(filename, randomized=randomized_name) @@ -251,8 +268,8 @@ class BaseFileStoreBackend: def iter_artifacts(self): for shard, key_file in self.iter_keys(): json_key = f"{shard.storage_medium}/{key_file}" - with shard.fs.open(json_key, 'rb') as f: - yield shard, json.loads(f.read())['filename_uid'] + with shard.fs.open(json_key, "rb") as f: + yield shard, json.loads(f.read())["filename_uid"] def get_statistics(self): total_files = 0 @@ -261,9 +278,9 @@ class BaseFileStoreBackend: for shard, key_file in self.iter_keys(): json_key = f"{shard.storage_medium}/{key_file}" - with shard.fs.open(json_key, 'rb') as f: + with shard.fs.open(json_key, "rb") as f: total_files += 1 metadata = json.loads(f.read()) - total_size += metadata['size'] + total_size += metadata["size"] return total_files, total_size, meta diff --git a/rhodecode/apps/file_store/backends/filesystem.py b/rhodecode/apps/file_store/backends/filesystem.py index 85c6ab51..ff90475a 100644 --- a/rhodecode/apps/file_store/backends/filesystem.py +++ b/rhodecode/apps/file_store/backends/filesystem.py @@ -32,9 +32,9 @@ log = logging.getLogger(__name__) class FileSystemShard(BaseShard): - METADATA_VER = 'v2' + METADATA_VER = "v2" BACKEND_TYPE = config_keys.backend_filesystem - storage_type: str = 'directory' + storage_type: str = "directory" def __init__(self, index, directory, directory_folder, fs, **settings): self._index: int = index @@ -47,8 +47,7 @@ class FileSystemShard(BaseShard): """Cache directory final path.""" return os.path.join(self._directory, self._directory_folder) - def _write_file(self, full_path, iterator, max_filesize, mode='wb'): - + def _write_file(self, full_path, iterator, max_filesize, mode="wb"): # ensure dir exists destination, _ = os.path.split(full_path) if not self.fs.exists(destination): @@ -79,14 +78,15 @@ class FileSystemShard(BaseShard): if oversize_cleanup: self.fs.rm(full_path) - raise FileOverSizeException(f'given file is over size limit ({max_filesize}): {full_path}') + raise FileOverSizeException(f"given file is over size limit ({max_filesize}): {full_path}") sha256 = digest.hexdigest() - log.debug('written new artifact under %s, sha256: %s', full_path, sha256) + log.debug("written new artifact under %s, sha256: %s", full_path, sha256) return size, sha256 - def _store(self, key: str, uid_key, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs): - + def _store( + self, key: str, uid_key, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs + ): filename = key uid_filename = uid_key full_path = self.store_path(uid_filename) @@ -95,33 +95,30 @@ class FileSystemShard(BaseShard): _metadata = { "version": self.METADATA_VER, "store_type": self.BACKEND_TYPE, - "filename": filename, "filename_uid_path": full_path, "filename_uid": uid_filename, "sha256": "", # NOTE: filled in by reader iteration - "store_time": time.time(), - - "size": 0 + "size": 0, } if metadata: - if kwargs.pop('import_mode', False): + if kwargs.pop("import_mode", False): # in import mode, we don't need to compute metadata, we just take the old version _metadata["import_mode"] = True else: _metadata.update(metadata) - read_iterator = iter(functools.partial(value_reader.read, 2**22), b'') + read_iterator = iter(functools.partial(value_reader.read, 2**22), b"") size, sha256 = self._write_file(full_path, read_iterator, max_filesize) - _metadata['size'] = size - _metadata['sha256'] = sha256 + _metadata["size"] = size + _metadata["sha256"] = sha256 # after storing the artifacts, we write the metadata present _metadata_file, metadata_file_path = self.get_metadata_filename(uid_key) - with self.fs.open(metadata_file_path, 'wb') as f: + with self.fs.open(metadata_file_path, "wb") as f: f.write(json.dumps(_metadata)) return uid_filename, _metadata @@ -134,23 +131,23 @@ class FileSystemShard(BaseShard): def _fetch(self, key, presigned_url_expires: int = 0): if key not in self: - log.exception(f'requested key={key} not found in {self}') + log.exception(f"requested key={key} not found in {self}") raise KeyError(key) metadata = self.get_metadata(key) - file_path = metadata['filename_uid_path'] + file_path = metadata["filename_uid_path"] if presigned_url_expires and presigned_url_expires > 0: - metadata['url'] = self.fs.url(file_path, expires=presigned_url_expires) + metadata["url"] = self.fs.url(file_path, expires=presigned_url_expires) - return ShardFileReader(self.fs.open(file_path, 'rb')), metadata + return ShardFileReader(self.fs.open(file_path, "rb")), metadata def delete(self, key): return self._delete(key) class FileSystemBackend(BaseFileStoreBackend): - shard_name: str = 'shard_{:03d}' + shard_name: str = "shard_{:03d}" _shard_cls = FileSystemShard def __init__(self, settings): @@ -163,10 +160,10 @@ class FileSystemBackend(BaseFileStoreBackend): self._storage_path = directory # common path for all from BaseCache self._shard_count = int(self.get_conf(config_keys.filesystem_shards, pop=True)) if self._shard_count < 1: - raise ValueError(f'{config_keys.filesystem_shards} must be 1 or more') + raise ValueError(f"{config_keys.filesystem_shards} must be 1 or more") - log.debug('Initializing %s file_store instance', self) - fs = fsspec.filesystem('file') + log.debug("Initializing %s file_store instance", self) + fs = fsspec.filesystem("file") if not fs.exists(self._directory): fs.makedirs(self._directory, exist_ok=True) diff --git a/rhodecode/apps/file_store/backends/filesystem_legacy.py b/rhodecode/apps/file_store/backends/filesystem_legacy.py index 4216175e..8db63359 100644 --- a/rhodecode/apps/file_store/backends/filesystem_legacy.py +++ b/rhodecode/apps/file_store/backends/filesystem_legacy.py @@ -33,12 +33,12 @@ log = logging.getLogger(__name__) class LegacyFileSystemShard(BaseShard): # legacy ver - METADATA_VER = 'v2' + METADATA_VER = "v2" BACKEND_TYPE = config_keys.backend_legacy_filesystem - storage_type: str = 'dir_struct' + storage_type: str = "dir_struct" # legacy suffix - metadata_suffix: str = '.meta' + metadata_suffix: str = ".meta" @classmethod def _sub_store_from_filename(cls, filename): @@ -46,7 +46,7 @@ class LegacyFileSystemShard(BaseShard): @classmethod def apply_counter(cls, counter, filename): - name_counted = '%d-%s' % (counter, filename) + name_counted = "%d-%s" % (counter, filename) return name_counted @classmethod @@ -93,10 +93,9 @@ class LegacyFileSystemShard(BaseShard): @property def dir_struct(self) -> str: """Cache directory final path.""" - return os.path.join(self._directory, '0-') - - def _write_file(self, full_path, iterator, max_filesize, mode='wb'): + return os.path.join(self._directory, "0-") + def _write_file(self, full_path, iterator, max_filesize, mode="wb"): # ensure dir exists destination, _ = os.path.split(full_path) if not self.fs.exists(destination): @@ -127,14 +126,15 @@ class LegacyFileSystemShard(BaseShard): if oversize_cleanup: self.fs.rm(full_path) - raise FileOverSizeException(f'given file is over size limit ({max_filesize}): {full_path}') + raise FileOverSizeException(f"given file is over size limit ({max_filesize}): {full_path}") sha256 = digest.hexdigest() - log.debug('written new artifact under %s, sha256: %s', full_path, sha256) + log.debug("written new artifact under %s, sha256: %s", full_path, sha256) return size, sha256 - def _store(self, key: str, uid_key, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs): - + def _store( + self, key: str, uid_key, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs + ): filename = key uid_filename = uid_key @@ -145,28 +145,25 @@ class LegacyFileSystemShard(BaseShard): # TODO: make it compatible, and backward proof _metadata = { "version": self.METADATA_VER, - "filename": filename, "filename_uid_path": full_path, "filename_uid": uid_filename, "sha256": "", # NOTE: filled in by reader iteration - "store_time": time.time(), - - "size": 0 + "size": 0, } if metadata: _metadata.update(metadata) - read_iterator = iter(functools.partial(value_reader.read, 2**22), b'') + read_iterator = iter(functools.partial(value_reader.read, 2**22), b"") size, sha256 = self._write_file(full_path, read_iterator, max_filesize) - _metadata['size'] = size - _metadata['sha256'] = sha256 + _metadata["size"] = size + _metadata["sha256"] = sha256 # after storing the artifacts, we write the metadata present _metadata_file, metadata_file_path = self.get_metadata_filename(uid_filename) - with self.fs.open(metadata_file_path, 'wb') as f: + with self.fs.open(metadata_file_path, "wb") as f: f.write(json.dumps(_metadata)) return uid_filename, _metadata @@ -175,9 +172,9 @@ class LegacyFileSystemShard(BaseShard): """ Returns absolute file path of the uid_filename """ - prefix_dir = '' - if '/' in uid_filename: - prefix_dir, filename = uid_filename.split('/') + prefix_dir = "" + if "/" in uid_filename: + prefix_dir, filename = uid_filename.split("/") sub_store = self._sub_store_from_filename(filename) else: sub_store = self._sub_store_from_filename(uid_filename) @@ -186,58 +183,54 @@ class LegacyFileSystemShard(BaseShard): def metadata_convert(self, uid_filename, metadata): # NOTE: backward compat mode here... this is for file created PRE 5.2 system - if 'meta_ver' in metadata: + if "meta_ver" in metadata: full_path = self.store_path(uid_filename) metadata = { "_converted": True, "_org": metadata, "version": self.METADATA_VER, "store_type": self.BACKEND_TYPE, - - "filename": metadata['filename'], + "filename": metadata["filename"], "filename_uid_path": full_path, "filename_uid": uid_filename, - "sha256": metadata['sha256'], - - "store_time": metadata['time'], - - "size": metadata['size'] + "sha256": metadata["sha256"], + "store_time": metadata["time"], + "size": metadata["size"], } return metadata def _fetch(self, key, presigned_url_expires: int = 0): if key not in self: - log.exception(f'requested key={key} not found in {self}') + log.exception(f"requested key={key} not found in {self}") raise KeyError(key) metadata = self.get_metadata(key) - file_path = metadata['filename_uid_path'] + file_path = metadata["filename_uid_path"] if presigned_url_expires and presigned_url_expires > 0: - metadata['url'] = self.fs.url(file_path, expires=presigned_url_expires) + metadata["url"] = self.fs.url(file_path, expires=presigned_url_expires) - return ShardFileReader(self.fs.open(file_path, 'rb')), metadata + return ShardFileReader(self.fs.open(file_path, "rb")), metadata def delete(self, key): return self._delete(key) def _delete(self, key): if key not in self: - log.exception(f'requested key={key} not found in {self}') + log.exception(f"requested key={key} not found in {self}") raise KeyError(key) metadata = self.get_metadata(key) metadata_file, metadata_file_path = self.get_metadata_filename(key) - artifact_file_path = metadata['filename_uid_path'] + artifact_file_path = metadata["filename_uid_path"] self.fs.rm(artifact_file_path) self.fs.rm(metadata_file_path) def get_metadata_filename(self, uid_filename) -> tuple[str, str]: - - metadata_file: str = f'{uid_filename}{self.metadata_suffix}' + metadata_file: str = f"{uid_filename}{self.metadata_suffix}" uid_path_in_store = self.store_path(uid_filename) - metadata_file_path = f'{uid_path_in_store}{self.metadata_suffix}' + metadata_file_path = f"{uid_path_in_store}{self.metadata_suffix}" return metadata_file, metadata_file_path @@ -253,8 +246,8 @@ class LegacyFileSystemBackend(BaseFileStoreBackend): self._directory = directory self._storage_path = directory # common path for all from BaseCache - log.debug('Initializing %s file_store instance', self) - fs = fsspec.filesystem('file') + log.debug("Initializing %s file_store instance", self) + fs = fsspec.filesystem("file") if not fs.exists(self._directory): fs.makedirs(self._directory, exist_ok=True) @@ -265,7 +258,7 @@ class LegacyFileSystemBackend(BaseFileStoreBackend): self._shard_cls( index=0, directory=directory, - directory_folder='', + directory_folder="", fs=fs, **settings, ) diff --git a/rhodecode/apps/file_store/backends/objectstore.py b/rhodecode/apps/file_store/backends/objectstore.py index ee8bef11..9f239566 100644 --- a/rhodecode/apps/file_store/backends/objectstore.py +++ b/rhodecode/apps/file_store/backends/objectstore.py @@ -32,9 +32,9 @@ log = logging.getLogger(__name__) class S3Shard(BaseShard): - METADATA_VER = 'v2' + METADATA_VER = "v2" BACKEND_TYPE = config_keys.backend_objectstore - storage_type: str = 'bucket' + storage_type: str = "bucket" def __init__(self, index, bucket, bucket_folder, fs, **settings): self._index: int = index @@ -48,8 +48,7 @@ class S3Shard(BaseShard): """Cache bucket final path.""" return os.path.join(self._bucket_main, self._bucket_folder) - def _write_file(self, full_path, iterator, max_filesize, mode='wb'): - + def _write_file(self, full_path, iterator, max_filesize, mode="wb"): # ensure dir exists destination, _ = os.path.split(full_path) if not self.fs.exists(destination): @@ -73,14 +72,15 @@ class S3Shard(BaseShard): if oversize_cleanup: self.fs.rm(full_path) - raise FileOverSizeException(f'given file is over size limit ({max_filesize}): {full_path}') + raise FileOverSizeException(f"given file is over size limit ({max_filesize}): {full_path}") sha256 = digest.hexdigest() - log.debug('written new artifact under %s, sha256: %s', full_path, sha256) + log.debug("written new artifact under %s, sha256: %s", full_path, sha256) return size, sha256 - def _store(self, key: str, uid_key, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs): - + def _store( + self, key: str, uid_key, value_reader, max_filesize: int | None = None, metadata: dict | None = None, **kwargs + ): filename = key uid_filename = uid_key full_path = self.store_path(uid_filename) @@ -89,33 +89,30 @@ class S3Shard(BaseShard): _metadata = { "version": self.METADATA_VER, "store_type": self.BACKEND_TYPE, - "filename": filename, "filename_uid_path": full_path, "filename_uid": uid_filename, "sha256": "", # NOTE: filled in by reader iteration - "store_time": time.time(), - - "size": 0 + "size": 0, } if metadata: - if kwargs.pop('import_mode', False): + if kwargs.pop("import_mode", False): # in import mode, we don't need to compute metadata, we just take the old version _metadata["import_mode"] = True else: _metadata.update(metadata) - read_iterator = iter(functools.partial(value_reader.read, 2**22), b'') + read_iterator = iter(functools.partial(value_reader.read, 2**22), b"") size, sha256 = self._write_file(full_path, read_iterator, max_filesize) - _metadata['size'] = size - _metadata['sha256'] = sha256 + _metadata["size"] = size + _metadata["sha256"] = sha256 # after storing the artifacts, we write the metadata present metadata_file, metadata_file_path = self.get_metadata_filename(uid_key) - with self.fs.open(metadata_file_path, 'wb') as f: + with self.fs.open(metadata_file_path, "wb") as f: f.write(json.dumps(_metadata)) return uid_filename, _metadata @@ -128,25 +125,25 @@ class S3Shard(BaseShard): def _fetch(self, key, presigned_url_expires: int = 0): if key not in self: - log.exception(f'requested key={key} not found in {self}') + log.exception(f"requested key={key} not found in {self}") raise KeyError(key) metadata_file, metadata_file_path = self.get_metadata_filename(key) - with self.fs.open(metadata_file_path, 'rb') as f: + with self.fs.open(metadata_file_path, "rb") as f: metadata = json.loads(f.read()) - file_path = metadata['filename_uid_path'] + file_path = metadata["filename_uid_path"] if presigned_url_expires and presigned_url_expires > 0: - metadata['url'] = self.fs.url(file_path, expires=presigned_url_expires) + metadata["url"] = self.fs.url(file_path, expires=presigned_url_expires) - return ShardFileReader(self.fs.open(file_path, 'rb')), metadata + return ShardFileReader(self.fs.open(file_path, "rb")), metadata def delete(self, key): return self._delete(key) class ObjectStoreBackend(BaseFileStoreBackend): - shard_name: str = 'shard-{:03d}' + shard_name: str = "shard-{:03d}" _shard_cls = S3Shard def __init__(self, settings): @@ -154,19 +151,19 @@ class ObjectStoreBackend(BaseFileStoreBackend): self._shard_count = int(self.get_conf(config_keys.objectstore_bucket_shards, pop=True)) if self._shard_count < 1: - raise ValueError('cache_shards must be 1 or more') + raise ValueError("cache_shards must be 1 or more") self._bucket = settings.pop(config_keys.objectstore_bucket) if not self._bucket: - raise ValueError(f'{config_keys.objectstore_bucket} needs to have a value') + raise ValueError(f"{config_keys.objectstore_bucket} needs to have a value") objectstore_url = self.get_conf(config_keys.objectstore_url) key = settings.pop(config_keys.objectstore_key) secret = settings.pop(config_keys.objectstore_secret) self._storage_path = objectstore_url # common path for all from BaseCache - log.debug('Initializing %s file_store instance', self) - fs = fsspec.filesystem('s3', anon=False, endpoint_url=objectstore_url, key=key, secret=secret) + log.debug("Initializing %s file_store instance", self) + fs = fsspec.filesystem("s3", anon=False, endpoint_url=objectstore_url, key=key, secret=secret) # init main bucket if not fs.exists(self._bucket): diff --git a/rhodecode/apps/file_store/config_keys.py b/rhodecode/apps/file_store/config_keys.py index 7b2ffe40..8686b451 100644 --- a/rhodecode/apps/file_store/config_keys.py +++ b/rhodecode/apps/file_store/config_keys.py @@ -21,16 +21,16 @@ # avoid repetition of keys throughout the module. # OLD and deprecated keys not used anymore -deprecated_enabled = 'file_store.enabled' -deprecated_backend = 'file_store.backend' -deprecated_store_path = 'file_store.storage_path' +deprecated_enabled = "file_store.enabled" +deprecated_backend = "file_store.backend" +deprecated_store_path = "file_store.storage_path" -backend_type = 'file_store.backend.type' +backend_type = "file_store.backend.type" -backend_legacy_filesystem = 'filesystem_v1' -backend_filesystem = 'filesystem_v2' -backend_objectstore = 'objectstore' +backend_legacy_filesystem = "filesystem_v1" +backend_filesystem = "filesystem_v2" +backend_objectstore = "objectstore" backend_types = [ backend_legacy_filesystem, @@ -39,19 +39,18 @@ backend_types = [ ] # filesystem_v1 legacy -legacy_filesystem_storage_path = 'file_store.filesystem_v1.storage_path' +legacy_filesystem_storage_path = "file_store.filesystem_v1.storage_path" # filesystem_v2 new option -filesystem_storage_path = 'file_store.filesystem_v2.storage_path' -filesystem_shards = 'file_store.filesystem_v2.shards' +filesystem_storage_path = "file_store.filesystem_v2.storage_path" +filesystem_shards = "file_store.filesystem_v2.shards" # objectstore -objectstore_url = 'file_store.objectstore.url' -objectstore_bucket = 'file_store.objectstore.bucket' -objectstore_bucket_shards = 'file_store.objectstore.bucket_shards' - -objectstore_region = 'file_store.objectstore.region' -objectstore_key = 'file_store.objectstore.key' -objectstore_secret = 'file_store.objectstore.secret' +objectstore_url = "file_store.objectstore.url" +objectstore_bucket = "file_store.objectstore.bucket" +objectstore_bucket_shards = "file_store.objectstore.bucket_shards" +objectstore_region = "file_store.objectstore.region" +objectstore_key = "file_store.objectstore.key" +objectstore_secret = "file_store.objectstore.secret" diff --git a/rhodecode/apps/file_store/extensions.py b/rhodecode/apps/file_store/extensions.py index b8bcc05e..6e973339 100644 --- a/rhodecode/apps/file_store/extensions.py +++ b/rhodecode/apps/file_store/extensions.py @@ -18,32 +18,34 @@ ANY = [] -TEXT_EXT = ['txt', 'md', 'rst', 'log'] -DOCUMENTS_EXT = ['pdf', 'rtf', 'odf', 'ods', 'gnumeric', 'abw', 'doc', 'docx', 'xls', 'xlsx'] -IMAGES_EXT = ['jpg', 'jpe', 'jpeg', 'png', 'gif', 'svg', 'bmp', 'tiff'] -AUDIO_EXT = ['wav', 'mp3', 'aac', 'ogg', 'oga', 'flac'] -VIDEO_EXT = ['mpeg', '3gp', 'avi', 'divx', 'dvr', 'flv', 'mp4', 'wmv'] -DATA_EXT = ['csv', 'ini', 'json', 'plist', 'xml', 'yaml', 'yml'] -SCRIPTS_EXT = ['js', 'php', 'pl', 'py', 'rb', 'sh', 'go', 'c', 'h'] -ARCHIVES_EXT = ['gz', 'bz2', 'zip', 'tar', 'tgz', 'txz', '7z'] -EXECUTABLES_EXT = ['so', 'exe', 'dll'] +TEXT_EXT = ["txt", "md", "rst", "log"] +DOCUMENTS_EXT = ["pdf", "rtf", "odf", "ods", "gnumeric", "abw", "doc", "docx", "xls", "xlsx"] +IMAGES_EXT = ["jpg", "jpe", "jpeg", "png", "gif", "svg", "bmp", "tiff"] +AUDIO_EXT = ["wav", "mp3", "aac", "ogg", "oga", "flac"] +VIDEO_EXT = ["mpeg", "3gp", "avi", "divx", "dvr", "flv", "mp4", "wmv"] +DATA_EXT = ["csv", "ini", "json", "plist", "xml", "yaml", "yml"] +SCRIPTS_EXT = ["js", "php", "pl", "py", "rb", "sh", "go", "c", "h"] +ARCHIVES_EXT = ["gz", "bz2", "zip", "tar", "tgz", "txz", "7z"] +EXECUTABLES_EXT = ["so", "exe", "dll"] DEFAULT = DOCUMENTS_EXT + TEXT_EXT + IMAGES_EXT + DATA_EXT -GROUPS = dict(( - ('any', ANY), - ('text', TEXT_EXT), - ('documents', DOCUMENTS_EXT), - ('images', IMAGES_EXT), - ('audio', AUDIO_EXT), - ('video', VIDEO_EXT), - ('data', DATA_EXT), - ('scripts', SCRIPTS_EXT), - ('archives', ARCHIVES_EXT), - ('executables', EXECUTABLES_EXT), - ('default', DEFAULT), -)) +GROUPS = dict( + ( + ("any", ANY), + ("text", TEXT_EXT), + ("documents", DOCUMENTS_EXT), + ("images", IMAGES_EXT), + ("audio", AUDIO_EXT), + ("video", VIDEO_EXT), + ("data", DATA_EXT), + ("scripts", SCRIPTS_EXT), + ("archives", ARCHIVES_EXT), + ("executables", EXECUTABLES_EXT), + ("default", DEFAULT), + ) +) def resolve_extensions(extensions, groups=None): diff --git a/rhodecode/apps/file_store/tests/__init__.py b/rhodecode/apps/file_store/tests/__init__.py index 674b62dc..699741a8 100644 --- a/rhodecode/apps/file_store/tests/__init__.py +++ b/rhodecode/apps/file_store/tests/__init__.py @@ -54,4 +54,4 @@ def random_binary_file(): def generate_random_filename(length=10): - return ''.join(random.choices(string.ascii_letters + string.digits, k=length)) \ No newline at end of file + return "".join(random.choices(string.ascii_letters + string.digits, k=length)) diff --git a/rhodecode/apps/file_store/tests/test_filestore_backends.py b/rhodecode/apps/file_store/tests/test_filestore_backends.py index df0082c2..ea5da755 100644 --- a/rhodecode/apps/file_store/tests/test_filestore_backends.py +++ b/rhodecode/apps/file_store/tests/test_filestore_backends.py @@ -29,35 +29,34 @@ from rhodecode.apps.file_store.tests import random_binary_file, file_store_insta class TestFileStoreBackends: - - @pytest.mark.parametrize('backend_type, expected_instance', [ - (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), - (config_keys.backend_filesystem, FileSystemBackend), - (config_keys.backend_objectstore, ObjectStoreBackend), - ]) + @pytest.mark.parametrize( + "backend_type, expected_instance", + [ + (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), + (config_keys.backend_filesystem, FileSystemBackend), + (config_keys.backend_objectstore, ObjectStoreBackend), + ], + ) def test_get_backend(self, backend_type, expected_instance, ini_settings): config = ini_settings config[config_keys.backend_type] = backend_type f_store = store_utils.get_filestore_backend(config=config, always_init=True) assert isinstance(f_store, expected_instance) - @pytest.mark.parametrize('backend_type, expected_instance', [ - (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), - (config_keys.backend_filesystem, FileSystemBackend), - (config_keys.backend_objectstore, ObjectStoreBackend), - ]) + @pytest.mark.parametrize( + "backend_type, expected_instance", + [ + (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), + (config_keys.backend_filesystem, FileSystemBackend), + (config_keys.backend_objectstore, ObjectStoreBackend), + ], + ) def test_store_and_read(self, backend_type, expected_instance, ini_settings, random_binary_file): filename, temp_file = random_binary_file config = ini_settings config[config_keys.backend_type] = backend_type f_store = store_utils.get_filestore_backend(config=config, always_init=True) - metadata = { - 'user_uploaded': { - 'username': 'user1', - 'user_id': 10, - 'ip': '10.20.30.40' - } - } + metadata = {"user_uploaded": {"username": "user1", "user_id": 10, "ip": "10.20.30.40"}} store_fid, metadata = f_store.store(filename, temp_file, extra_metadata=metadata) assert store_fid assert metadata @@ -65,39 +64,52 @@ class TestFileStoreBackends: # read-after write reader, metadata2 = f_store.fetch(store_fid) assert reader - assert metadata2['filename'] == filename + assert metadata2["filename"] == filename - @pytest.mark.parametrize('backend_type, expected_instance', [ - (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), - (config_keys.backend_filesystem, FileSystemBackend), - (config_keys.backend_objectstore, ObjectStoreBackend), - ]) + @pytest.mark.parametrize( + "backend_type, expected_instance", + [ + (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), + (config_keys.backend_filesystem, FileSystemBackend), + (config_keys.backend_objectstore, ObjectStoreBackend), + ], + ) def test_store_file_not_allowed(self, backend_type, expected_instance, ini_settings, random_binary_file): filename, temp_file = random_binary_file config = ini_settings config[config_keys.backend_type] = backend_type f_store = store_utils.get_filestore_backend(config=config, always_init=True) with pytest.raises(FileNotAllowedException): - f_store.store('notallowed.exe', temp_file, extensions=['.txt']) + f_store.store("notallowed.exe", temp_file, extensions=[".txt"]) - @pytest.mark.parametrize('backend_type, expected_instance', [ - (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), - (config_keys.backend_filesystem, FileSystemBackend), - (config_keys.backend_objectstore, ObjectStoreBackend), - ]) + @pytest.mark.parametrize( + "backend_type, expected_instance", + [ + (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend), + (config_keys.backend_filesystem, FileSystemBackend), + (config_keys.backend_objectstore, ObjectStoreBackend), + ], + ) def test_store_file_over_size(self, backend_type, expected_instance, ini_settings, random_binary_file): filename, temp_file = random_binary_file config = ini_settings config[config_keys.backend_type] = backend_type f_store = store_utils.get_filestore_backend(config=config, always_init=True) with pytest.raises(FileOverSizeException): - f_store.store('toobig.exe', temp_file, extensions=['.exe'], max_filesize=124) + f_store.store("toobig.exe", temp_file, extensions=[".exe"], max_filesize=124) - @pytest.mark.parametrize('backend_type, expected_instance, extra_conf', [ - (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend, {}), - (config_keys.backend_filesystem, FileSystemBackend, {config_keys.filesystem_storage_path: '/tmp/test-fs-store'}), - (config_keys.backend_objectstore, ObjectStoreBackend, {config_keys.objectstore_bucket: 'test-bucket'}), - ]) + @pytest.mark.parametrize( + "backend_type, expected_instance, extra_conf", + [ + (config_keys.backend_legacy_filesystem, LegacyFileSystemBackend, {}), + ( + config_keys.backend_filesystem, + FileSystemBackend, + {config_keys.filesystem_storage_path: "/tmp/test-fs-store"}, + ), + (config_keys.backend_objectstore, ObjectStoreBackend, {config_keys.objectstore_bucket: "test-bucket"}), + ], + ) def test_store_stats_and_keys(self, backend_type, expected_instance, extra_conf, ini_settings, random_binary_file): config = ini_settings config[config_keys.backend_type] = backend_type @@ -112,13 +124,7 @@ class TestFileStoreBackends: for i in range(10): filename, temp_file = random_binary_file - metadata = { - 'user_uploaded': { - 'username': 'user1', - 'user_id': 10, - 'ip': '10.20.30.40' - } - } + metadata = {"user_uploaded": {"username": "user1", "user_id": 10, "ip": "10.20.30.40"}} store_fid, metadata = f_store.store(filename, temp_file, extra_metadata=metadata) assert store_fid assert metadata diff --git a/rhodecode/apps/file_store/tests/test_filestore_filesystem_backend.py b/rhodecode/apps/file_store/tests/test_filestore_filesystem_backend.py index ad423b9d..052bea34 100644 --- a/rhodecode/apps/file_store/tests/test_filestore_filesystem_backend.py +++ b/rhodecode/apps/file_store/tests/test_filestore_filesystem_backend.py @@ -31,22 +31,27 @@ def file_store_filesystem_instance(ini_settings): class TestFileStoreFileSystemBackend: - - @pytest.mark.parametrize('filename', [generate_random_filename() for _ in range(10)]) + @pytest.mark.parametrize("filename", [generate_random_filename() for _ in range(10)]) def test_get_shard_number(self, filename, file_store_filesystem_instance): - shard_number = file_store_filesystem_instance.get_shard_index(filename, len(file_store_filesystem_instance._shards)) + shard_number = file_store_filesystem_instance.get_shard_index( + filename, len(file_store_filesystem_instance._shards) + ) # Check that the shard number is between 0 and max-shards assert 0 <= shard_number <= len(file_store_filesystem_instance._shards) - @pytest.mark.parametrize('filename, expected_shard_num', [ - ('my-name-1', 3), - ('my-name-2', 2), - ('my-name-3', 4), - ('my-name-4', 1), - - ('rhodecode-enterprise-ce', 5), - ('rhodecode-enterprise-ee', 6), - ]) + @pytest.mark.parametrize( + "filename, expected_shard_num", + [ + ("my-name-1", 3), + ("my-name-2", 2), + ("my-name-3", 4), + ("my-name-4", 1), + ("rhodecode-enterprise-ce", 5), + ("rhodecode-enterprise-ee", 6), + ], + ) def test_get_shard_number_consistency(self, filename, expected_shard_num, file_store_filesystem_instance): - shard_number = file_store_filesystem_instance.get_shard_index(filename, len(file_store_filesystem_instance._shards)) + shard_number = file_store_filesystem_instance.get_shard_index( + filename, len(file_store_filesystem_instance._shards) + ) assert expected_shard_num == shard_number diff --git a/rhodecode/apps/file_store/tests/test_filestore_legacy_and_v2_compatability.py b/rhodecode/apps/file_store/tests/test_filestore_legacy_and_v2_compatability.py index 7d42e202..ae06165a 100644 --- a/rhodecode/apps/file_store/tests/test_filestore_legacy_and_v2_compatability.py +++ b/rhodecode/apps/file_store/tests/test_filestore_legacy_and_v2_compatability.py @@ -14,4 +14,4 @@ # # This program is dual-licensed. If you wish to learn more about the # RhodeCode Enterprise Edition, including its added features, Support services, -# and proprietary license terms, please see https://rhodecode.com/licenses/ \ No newline at end of file +# and proprietary license terms, please see https://rhodecode.com/licenses/ diff --git a/rhodecode/apps/file_store/tests/test_filestore_legacy_backend.py b/rhodecode/apps/file_store/tests/test_filestore_legacy_backend.py index ec2547c9..20682c22 100644 --- a/rhodecode/apps/file_store/tests/test_filestore_legacy_backend.py +++ b/rhodecode/apps/file_store/tests/test_filestore_legacy_backend.py @@ -31,22 +31,23 @@ def file_store_legacy_instance(ini_settings): class TestFileStoreLegacyBackend: - - @pytest.mark.parametrize('filename', [generate_random_filename() for _ in range(10)]) + @pytest.mark.parametrize("filename", [generate_random_filename() for _ in range(10)]) def test_get_shard_number(self, filename, file_store_legacy_instance): shard_number = file_store_legacy_instance.get_shard_index(filename, len(file_store_legacy_instance._shards)) # Check that the shard number is 0 for legacy filesystem store we don't use shards assert shard_number == 0 - @pytest.mark.parametrize('filename, expected_shard_num', [ - ('my-name-1', 0), - ('my-name-2', 0), - ('my-name-3', 0), - ('my-name-4', 0), - - ('rhodecode-enterprise-ce', 0), - ('rhodecode-enterprise-ee', 0), - ]) + @pytest.mark.parametrize( + "filename, expected_shard_num", + [ + ("my-name-1", 0), + ("my-name-2", 0), + ("my-name-3", 0), + ("my-name-4", 0), + ("rhodecode-enterprise-ce", 0), + ("rhodecode-enterprise-ee", 0), + ], + ) def test_get_shard_number_consistency(self, filename, expected_shard_num, file_store_legacy_instance): shard_number = file_store_legacy_instance.get_shard_index(filename, len(file_store_legacy_instance._shards)) assert expected_shard_num == shard_number diff --git a/rhodecode/apps/file_store/tests/test_filestore_objectstore_backend.py b/rhodecode/apps/file_store/tests/test_filestore_objectstore_backend.py index 3a37523d..02dfc536 100644 --- a/rhodecode/apps/file_store/tests/test_filestore_objectstore_backend.py +++ b/rhodecode/apps/file_store/tests/test_filestore_objectstore_backend.py @@ -31,22 +31,27 @@ def file_store_objectstore_instance(ini_settings): class TestFileStoreObjectStoreBackend: - - @pytest.mark.parametrize('filename', [generate_random_filename() for _ in range(10)]) + @pytest.mark.parametrize("filename", [generate_random_filename() for _ in range(10)]) def test_get_shard_number(self, filename, file_store_objectstore_instance): - shard_number = file_store_objectstore_instance.get_shard_index(filename, len(file_store_objectstore_instance._shards)) + shard_number = file_store_objectstore_instance.get_shard_index( + filename, len(file_store_objectstore_instance._shards) + ) # Check that the shard number is between 0 and shards assert 0 <= shard_number <= len(file_store_objectstore_instance._shards) - @pytest.mark.parametrize('filename, expected_shard_num', [ - ('my-name-1', 3), - ('my-name-2', 2), - ('my-name-3', 4), - ('my-name-4', 1), - - ('rhodecode-enterprise-ce', 5), - ('rhodecode-enterprise-ee', 6), - ]) + @pytest.mark.parametrize( + "filename, expected_shard_num", + [ + ("my-name-1", 3), + ("my-name-2", 2), + ("my-name-3", 4), + ("my-name-4", 1), + ("rhodecode-enterprise-ce", 5), + ("rhodecode-enterprise-ee", 6), + ], + ) def test_get_shard_number_consistency(self, filename, expected_shard_num, file_store_objectstore_instance): - shard_number = file_store_objectstore_instance.get_shard_index(filename, len(file_store_objectstore_instance._shards)) + shard_number = file_store_objectstore_instance.get_shard_index( + filename, len(file_store_objectstore_instance._shards) + ) assert expected_shard_num == shard_number diff --git a/rhodecode/apps/file_store/tests/test_upload_file.py b/rhodecode/apps/file_store/tests/test_upload_file.py index 82639943..3f22641e 100644 --- a/rhodecode/apps/file_store/tests/test_upload_file.py +++ b/rhodecode/apps/file_store/tests/test_upload_file.py @@ -31,45 +31,49 @@ from rhodecode.tests.routes import route_path class TestFileStoreViews(TestController): - @pytest.fixture() def create_artifact_factory(self, tmpdir, ini_settings): - - def factory(user_id, content, f_name='example.txt'): - + def factory(user_id, content, f_name="example.txt"): config = ini_settings config[config_keys.backend_type] = config_keys.backend_legacy_filesystem f_store = store_utils.get_filestore_backend(config) filesystem_file = os.path.join(str(tmpdir), f_name) - with open(filesystem_file, 'wt') as f: + with open(filesystem_file, "wt") as f: f.write(content) - with open(filesystem_file, 'rb') as f: - store_uid, metadata = f_store.store(f_name, f, metadata={'filename': f_name}) + with open(filesystem_file, "rb") as f: + store_uid, metadata = f_store.store(f_name, f, metadata={"filename": f_name}) os.remove(filesystem_file) entry = FileStore.create( - file_uid=store_uid, filename=metadata["filename"], - file_hash=metadata["sha256"], file_size=metadata["size"], - file_display_name='file_display_name', - file_description='repo artifact `{}`'.format(metadata["filename"]), - check_acl=True, user_id=user_id, + file_uid=store_uid, + filename=metadata["filename"], + file_hash=metadata["sha256"], + file_size=metadata["size"], + file_display_name="file_display_name", + file_description="repo artifact `{}`".format(metadata["filename"]), + check_acl=True, + user_id=user_id, ) Session().add(entry) Session().commit() return entry + return factory - @pytest.mark.parametrize("fid, content, exists", [ - ('abcde-0.jpg', "xxxxx", True), - ('abcde-0.exe', "1234567", True), - ('abcde-0.jpg', "xxxxx", False), - ]) + @pytest.mark.parametrize( + "fid, content, exists", + [ + ("abcde-0.jpg", "xxxxx", True), + ("abcde-0.exe", "1234567", True), + ("abcde-0.jpg", "xxxxx", False), + ], + ) def test_get_files_from_store(self, fid, content, exists, tmpdir, user_util, ini_settings): user = self.log_user() - user_id = user['user_id'] + user_id = user["user_id"] repo_id = user_util.create_repo().repo_id config = ini_settings @@ -81,20 +85,23 @@ class TestFileStoreViews(TestController): status = 200 f_store = store_utils.get_filestore_backend(config) filesystem_file = os.path.join(str(tmpdir), fid) - with open(filesystem_file, 'wt') as f: + with open(filesystem_file, "wt") as f: f.write(content) - with open(filesystem_file, 'rb') as f: - store_uid, metadata = f_store.store(fid, f, metadata={'filename': fid}) + with open(filesystem_file, "rb") as f: + store_uid, metadata = f_store.store(fid, f, metadata={"filename": fid}) os.remove(filesystem_file) entry = FileStore.create( - file_uid=store_uid, filename=metadata["filename"], - file_hash=metadata["sha256"], file_size=metadata["size"], - file_display_name='file_display_name', - file_description='repo artifact `{}`'.format(metadata["filename"]), - check_acl=True, user_id=user_id, - scope_repo_id=repo_id + file_uid=store_uid, + filename=metadata["filename"], + file_hash=metadata["sha256"], + file_size=metadata["size"], + file_display_name="file_display_name", + file_description="repo artifact `{}`".format(metadata["filename"]), + check_acl=True, + user_id=user_id, + scope_repo_id=repo_id, ) Session().add(entry) Session().commit() @@ -102,69 +109,64 @@ class TestFileStoreViews(TestController): else: status = 404 - response = self.app.get(route_path('download_file', fid=store_uid), status=status) + response = self.app.get(route_path("download_file", fid=store_uid), status=status) if exists: assert response.text == content metadata = f_store.get_metadata(store_uid) - assert 'size' in metadata + assert "size" in metadata def test_upload_files_without_content_to_store(self): self.log_user() - response = self.app.post( - route_path('upload_file'), - params={'csrf_token': self.csrf_token}, - status=200) + response = self.app.post(route_path("upload_file"), params={"csrf_token": self.csrf_token}, status=200) - assert response.json == { - 'error': 'store_file data field is missing', - 'access_path': None, - 'store_fid': None} + assert response.json == {"error": "store_file data field is missing", "access_path": None, "store_fid": None} def test_upload_files_bogus_content_to_store(self): self.log_user() response = self.app.post( - route_path('upload_file'), - params={'csrf_token': self.csrf_token, 'store_file': 'bogus'}, - status=200) + route_path("upload_file"), params={"csrf_token": self.csrf_token, "store_file": "bogus"}, status=200 + ) assert response.json == { - 'error': 'filename cannot be read from the data field', - 'access_path': None, - 'store_fid': None} + "error": "filename cannot be read from the data field", + "access_path": None, + "store_fid": None, + } def test_upload_content_to_store(self): self.log_user() response = self.app.post( - route_path('upload_file'), - upload_files=[('store_file', b'myfile.txt', b'SOME CONTENT')], - params={'csrf_token': self.csrf_token}, - status=200) + route_path("upload_file"), + upload_files=[("store_file", b"myfile.txt", b"SOME CONTENT")], + params={"csrf_token": self.csrf_token}, + status=200, + ) - assert response.json['store_fid'] + assert response.json["store_fid"] def test_download_file_non_scoped(self, user_util, create_artifact_factory): user = self.log_user() - user_id = user['user_id'] - content = 'HELLO MY NAME IS ARTIFACT !' + user_id = user["user_id"] + content = "HELLO MY NAME IS ARTIFACT !" artifact = create_artifact_factory(user_id, content) file_uid = artifact.file_uid - response = self.app.get(route_path('download_file', fid=file_uid), status=200) + response = self.app.get(route_path("download_file", fid=file_uid), status=200) assert response.text == content # log-in to new user and test download again - user = user_util.create_user(password='qweqwe') - self.log_user(user.username, 'qweqwe') - response = self.app.get(route_path('download_file', fid=file_uid), status=200) + user = user_util.create_user(password="qweqwe") + self.log_user(user.username, "qweqwe") + response = self.app.get(route_path("download_file", fid=file_uid), status=200) assert response.text == content def test_download_file_scoped_to_repo(self, user_util, create_artifact_factory): user = self.log_user() - user_id = user['user_id'] - content = 'HELLO MY NAME IS ARTIFACT !' + user_id = user["user_id"] + content = "HELLO MY NAME IS ARTIFACT !" artifact = create_artifact_factory(user_id, content) # bind to repo @@ -175,28 +177,28 @@ class TestFileStoreViews(TestController): Session().commit() file_uid = artifact.file_uid - response = self.app.get(route_path('download_file', fid=file_uid), status=200) + response = self.app.get(route_path("download_file", fid=file_uid), status=200) assert response.text == content # log-in to new user and test download again - user = user_util.create_user(password='qweqwe') - self.log_user(user.username, 'qweqwe') - response = self.app.get(route_path('download_file', fid=file_uid), status=200) + user = user_util.create_user(password="qweqwe") + self.log_user(user.username, "qweqwe") + response = self.app.get(route_path("download_file", fid=file_uid), status=200) assert response.text == content # forbid user the rights to repo repo = Repository.get(repo_id) - user_util.grant_user_permission_to_repo(repo, user, 'repository.none') - self.app.get(route_path('download_file', fid=file_uid), status=404) + user_util.grant_user_permission_to_repo(repo, user, "repository.none") + self.app.get(route_path("download_file", fid=file_uid), status=404) def test_download_file_scoped_to_user(self, user_util, create_artifact_factory): user = self.log_user() - user_id = user['user_id'] - content = 'HELLO MY NAME IS ARTIFACT !' + user_id = user["user_id"] + content = "HELLO MY NAME IS ARTIFACT !" artifact = create_artifact_factory(user_id, content) # bind to user - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") artifact.scope_user_id = user.user_id Session().add(artifact) @@ -204,16 +206,16 @@ class TestFileStoreViews(TestController): # artifact creator doesn't have access since it's bind to another user file_uid = artifact.file_uid - self.app.get(route_path('download_file', fid=file_uid), status=404) + self.app.get(route_path("download_file", fid=file_uid), status=404) # log-in to new user and test download again, should be ok since we're bind to this artifact - self.log_user(user.username, 'qweqwe') - response = self.app.get(route_path('download_file', fid=file_uid), status=200) + self.log_user(user.username, "qweqwe") + response = self.app.get(route_path("download_file", fid=file_uid), status=200) assert response.text == content def test_download_file_scoped_to_repo_with_bad_token(self, user_util, create_artifact_factory): user_id = User.get_first_super_admin().user_id - content = 'HELLO MY NAME IS ARTIFACT !' + content = "HELLO MY NAME IS ARTIFACT !" artifact = create_artifact_factory(user_id, content) # bind to repo @@ -224,19 +226,17 @@ class TestFileStoreViews(TestController): Session().commit() file_uid = artifact.file_uid - self.app.get(route_path('download_file_by_token', - _auth_token='bogus', fid=file_uid), status=302) + self.app.get(route_path("download_file_by_token", _auth_token="bogus", fid=file_uid), status=302) def test_download_file_scoped_to_repo_with_token(self, user_util, create_artifact_factory): user = User.get_first_super_admin() - AuthTokenModel().create(user, 'test artifact token', - role=AuthTokenModel.cls.ROLE_ARTIFACT_DOWNLOAD) + AuthTokenModel().create(user, "test artifact token", role=AuthTokenModel.cls.ROLE_ARTIFACT_DOWNLOAD) user = User.get_first_super_admin() artifact_token = user.artifact_token user_id = User.get_first_super_admin().user_id - content = 'HELLO MY NAME IS ARTIFACT !' + content = "HELLO MY NAME IS ARTIFACT !" artifact = create_artifact_factory(user_id, content) # bind to repo @@ -248,6 +248,6 @@ class TestFileStoreViews(TestController): file_uid = artifact.file_uid response = self.app.get( - route_path('download_file_by_token', - _auth_token=artifact_token, fid=file_uid), status=200) + route_path("download_file_by_token", _auth_token=artifact_token, fid=file_uid), status=200 + ) assert response.text == content diff --git a/rhodecode/apps/file_store/utils.py b/rhodecode/apps/file_store/utils.py index d08e4605..5efcc71a 100755 --- a/rhodecode/apps/file_store/utils.py +++ b/rhodecode/apps/file_store/utils.py @@ -29,11 +29,10 @@ file_store_meta = None def get_filestore_config(config) -> dict: - final_config = {} for k, v in config.items(): - if k.startswith('file_store'): + if k.startswith("file_store"): final_config[k] = v return final_config @@ -62,23 +61,18 @@ def get_filestore_backend(config, always_init=False): case config_keys.backend_legacy_filesystem: # Legacy backward compatible storage from rhodecode.apps.file_store.backends.filesystem_legacy import LegacyFileSystemBackend - d_cache = LegacyFileSystemBackend( - settings=config - ) + + d_cache = LegacyFileSystemBackend(settings=config) case config_keys.backend_filesystem: from rhodecode.apps.file_store.backends.filesystem import FileSystemBackend - d_cache = FileSystemBackend( - settings=config - ) + + d_cache = FileSystemBackend(settings=config) case config_keys.backend_objectstore: from rhodecode.apps.file_store.backends.objectstore import ObjectStoreBackend - d_cache = ObjectStoreBackend( - settings=config - ) + + d_cache = ObjectStoreBackend(settings=config) case _: - raise ValueError( - f'file_store.backend.type only supports "{config_keys.backend_types}" got {backend}' - ) + raise ValueError(f'file_store.backend.type only supports "{config_keys.backend_types}" got {backend}') cache_meta = d_cache return cache_meta @@ -92,7 +86,7 @@ def splitext(filename): suffix = " ".join(suffix.split()).replace(" ", "") final_ext.append(suffix) - ext = ''.join(final_ext) + ext = "".join(final_ext) return filename, ext @@ -110,7 +104,7 @@ def get_uid_filename(filename, randomized=True): uid = uuid.uuid4() else: store_suffix = "store" - hash_key = f'{filename}.{store_suffix}' + hash_key = f"{filename}.{store_suffix}" uid = uuid.uuid5(uuid.NAMESPACE_URL, hash_key) return str(uid) + ext.lower() @@ -120,14 +114,13 @@ def bytes_to_file_obj(bytes_data): class ShardFileReader: - def __init__(self, file_like_reader): self._file_like_reader = file_like_reader def __getattr__(self, item): if isinstance(self._file_like_reader, s3fs.core.S3File): match item: - case 'name': + case "name": # S3 FileWrapper doesn't support name attribute, and we use it return self._file_like_reader.full_name case _: diff --git a/rhodecode/apps/file_store/views.py b/rhodecode/apps/file_store/views.py index fa71da92..31975077 100644 --- a/rhodecode/apps/file_store/views.py +++ b/rhodecode/apps/file_store/views.py @@ -22,14 +22,17 @@ from pyramid.httpexceptions import HTTPFound, HTTPNotFound from rhodecode.apps._base import BaseAppView from rhodecode.apps.file_store import utils as store_utils -from rhodecode.apps.file_store.exceptions import ( - FileNotAllowedException, FileOverSizeException) +from rhodecode.apps.file_store.exceptions import FileNotAllowedException, FileOverSizeException from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger from rhodecode.lib.auth import ( - CSRFRequired, NotAnonymous, HasRepoPermissionAny, HasRepoGroupPermissionAny, - LoginRequired) + CSRFRequired, + NotAnonymous, + HasRepoPermissionAny, + HasRepoGroupPermissionAny, + LoginRequired, +) from rhodecode.lib.str_utils import header_safe_str from rhodecode.lib.vcs.conf.mtypes import get_mimetypes_db from rhodecode.model.db import Session, FileStore, UserApiKeys @@ -38,7 +41,7 @@ log = logging.getLogger(__name__) class FileStoreView(BaseAppView): - upload_key = 'store_file' + upload_key = "store_file" def load_default_context(self): c = self._get_local_tmpl_context() @@ -49,7 +52,7 @@ class FileStoreView(BaseAppView): """ Our own type guesser for mimetypes using the rich DB """ - if not hasattr(self, 'db'): + if not hasattr(self, "db"): self.db = get_mimetypes_db() _content_type, _encoding = self.db.guess_type(file_name, strict=False) return _content_type, _encoding @@ -57,8 +60,7 @@ class FileStoreView(BaseAppView): def _serve_file(self, file_uid): if not self.f_store.filename_exists(file_uid): store_path = self.f_store.store_path(file_uid) - log.warning('File with FID:%s not found in the store under `%s`', - file_uid, store_path) + log.warning("File with FID:%s not found in the store under `%s`", file_uid, store_path) raise HTTPNotFound() db_obj = FileStore.get_by_store_uid(file_uid, safe=True) @@ -67,39 +69,36 @@ class FileStoreView(BaseAppView): # private upload for user if db_obj.check_acl and db_obj.scope_user_id: - log.debug('Artifact: checking scope access for bound artifact user: `%s`', - db_obj.scope_user_id) + log.debug("Artifact: checking scope access for bound artifact user: `%s`", db_obj.scope_user_id) user = db_obj.user if self._rhodecode_db_user.user_id != user.user_id: - log.warning('Access to file store object forbidden') + log.warning("Access to file store object forbidden") raise HTTPNotFound() # scoped to repository permissions if db_obj.check_acl and db_obj.scope_repo_id: - log.debug('Artifact: checking scope access for bound artifact repo: `%s`', - db_obj.scope_repo_id) + log.debug("Artifact: checking scope access for bound artifact repo: `%s`", db_obj.scope_repo_id) repo = db_obj.repo - perm_set = ['repository.read', 'repository.write', 'repository.admin'] - has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'FileStore check') + perm_set = ["repository.read", "repository.write", "repository.admin"] + has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, "FileStore check") if not has_perm: - log.warning('Access to file store object `%s` forbidden', file_uid) + log.warning("Access to file store object `%s` forbidden", file_uid) raise HTTPNotFound() # scoped to repository group permissions if db_obj.check_acl and db_obj.scope_repo_group_id: - log.debug('Artifact: checking scope access for bound artifact repo group: `%s`', - db_obj.scope_repo_group_id) + log.debug("Artifact: checking scope access for bound artifact repo group: `%s`", db_obj.scope_repo_group_id) repo_group = db_obj.repo_group - perm_set = ['group.read', 'group.write', 'group.admin'] - has_perm = HasRepoGroupPermissionAny(*perm_set)(repo_group.group_name, 'FileStore check') + perm_set = ["group.read", "group.write", "group.admin"] + has_perm = HasRepoGroupPermissionAny(*perm_set)(repo_group.group_name, "FileStore check") if not has_perm: - log.warning('Access to file store object `%s` forbidden', file_uid) + log.warning("Access to file store object `%s` forbidden", file_uid) raise HTTPNotFound() FileStore.bump_access_counter(file_uid) file_name = db_obj.file_display_name - content_type = 'application/octet-stream' + content_type = "application/octet-stream" _content_type, _encoding = self._guess_type(file_name) if _content_type: @@ -107,7 +106,7 @@ class FileStoreView(BaseAppView): # For file store we don't submit any session data, this logic tells the # Session lib to skip it - setattr(self.request, '_file_response', True) + setattr(self.request, "_file_response", True) reader, _meta = self.f_store.fetch(file_uid) response = Response(app_iter=store_utils.archive_iterator(reader)) @@ -128,58 +127,52 @@ class FileStoreView(BaseAppView): file_obj = self.request.POST.get(self.upload_key) if file_obj is None: - return {'store_fid': None, - 'access_path': None, - 'error': f'{self.upload_key} data field is missing'} + return {"store_fid": None, "access_path": None, "error": f"{self.upload_key} data field is missing"} - if not hasattr(file_obj, 'filename'): - return {'store_fid': None, - 'access_path': None, - 'error': 'filename cannot be read from the data field'} + if not hasattr(file_obj, "filename"): + return {"store_fid": None, "access_path": None, "error": "filename cannot be read from the data field"} filename = file_obj.filename metadata = { - 'user_uploaded': {'username': self._rhodecode_user.username, - 'user_id': self._rhodecode_user.user_id, - 'ip': self._rhodecode_user.ip_addr}} + "user_uploaded": { + "username": self._rhodecode_user.username, + "user_id": self._rhodecode_user.user_id, + "ip": self._rhodecode_user.ip_addr, + } + } try: - store_uid, metadata = self.f_store.store( - filename, file_obj.file, extra_metadata=metadata) + store_uid, metadata = self.f_store.store(filename, file_obj.file, extra_metadata=metadata) except FileNotAllowedException: - return {'store_fid': None, - 'access_path': None, - 'error': f'File {filename} is not allowed.'} + return {"store_fid": None, "access_path": None, "error": f"File {filename} is not allowed."} except FileOverSizeException: - return {'store_fid': None, - 'access_path': None, - 'error': f'File {filename} is exceeding allowed limit.'} + return {"store_fid": None, "access_path": None, "error": f"File {filename} is exceeding allowed limit."} try: entry = FileStore.create( - file_uid=store_uid, filename=metadata["filename"], - file_hash=metadata["sha256"], file_size=metadata["size"], - file_description='upload attachment', - check_acl=False, user_id=self._rhodecode_user.user_id + file_uid=store_uid, + filename=metadata["filename"], + file_hash=metadata["sha256"], + file_size=metadata["size"], + file_description="upload attachment", + check_acl=False, + user_id=self._rhodecode_user.user_id, ) Session().add(entry) Session().commit() - log.debug('Stored upload in DB as %s', entry) + log.debug("Stored upload in DB as %s", entry) except Exception: - log.exception('Failed to store file %s', filename) - return {'store_fid': None, - 'access_path': None, - 'error': f'File {filename} failed to store in DB.'} + log.exception("Failed to store file %s", filename) + return {"store_fid": None, "access_path": None, "error": f"File {filename} failed to store in DB."} - return {'store_fid': store_uid, - 'access_path': h.route_path('download_file', fid=store_uid)} + return {"store_fid": store_uid, "access_path": h.route_path("download_file", fid=store_uid)} # ACL is checked by scopes, if no scope the file is accessible to all def download_file(self): self.load_default_context() - file_uid = self.request.matchdict['fid'] - log.debug('Requesting FID:%s from store %s', file_uid, self.f_store) + file_uid = self.request.matchdict["fid"] + log.debug("Requesting FID:%s from store %s", file_uid, self.f_store) return self._serve_file(file_uid) # in addition to @LoginRequired ACL is checked by scopes @@ -193,5 +186,5 @@ class FileStoreView(BaseAppView): http://example.com/_file_store/token-download/TOKEN/FILE_UID """ self.load_default_context() - file_uid = self.request.matchdict['fid'] + file_uid = self.request.matchdict["fid"] return self._serve_file(file_uid) diff --git a/rhodecode/apps/gist/__init__.py b/rhodecode/apps/gist/__init__.py index 1c327136..df4fd5f5 100644 --- a/rhodecode/apps/gist/__init__.py +++ b/rhodecode/apps/gist/__init__.py @@ -21,97 +21,89 @@ from rhodecode.apps._base import ADMIN_PREFIX def admin_routes(config): from rhodecode.apps.gist.views import GistView - config.add_route( - name='gists_show', pattern='/gists') + config.add_route(name="gists_show", pattern="/gists") config.add_view( GistView, - attr='gist_show_all', - route_name='gists_show', request_method='GET', - renderer='rhodecode:templates/admin/gists/gist_index.mako') + attr="gist_show_all", + route_name="gists_show", + request_method="GET", + renderer="rhodecode:templates/admin/gists/gist_index.mako", + ) - config.add_route( - name='gists_new', pattern='/gists/new') + config.add_route(name="gists_new", pattern="/gists/new") config.add_view( GistView, - attr='gist_new', - route_name='gists_new', request_method='GET', - renderer='rhodecode:templates/admin/gists/gist_new.mako') + attr="gist_new", + route_name="gists_new", + request_method="GET", + renderer="rhodecode:templates/admin/gists/gist_new.mako", + ) - config.add_route( - name='gists_create', pattern='/gists/create') + config.add_route(name="gists_create", pattern="/gists/create") config.add_view( GistView, - attr='gist_create', - route_name='gists_create', request_method='POST', - renderer='rhodecode:templates/admin/gists/gist_new.mako') + attr="gist_create", + route_name="gists_create", + request_method="POST", + renderer="rhodecode:templates/admin/gists/gist_new.mako", + ) - config.add_route( - name='gist_show', pattern='/gists/{gist_id}') + config.add_route(name="gist_show", pattern="/gists/{gist_id}") config.add_view( GistView, - attr='gist_show', - route_name='gist_show', request_method='GET', - renderer='rhodecode:templates/admin/gists/gist_show.mako') + attr="gist_show", + route_name="gist_show", + request_method="GET", + renderer="rhodecode:templates/admin/gists/gist_show.mako", + ) - config.add_route( - name='gist_show_rev', - pattern='/gists/{gist_id}/rev/{revision}') + config.add_route(name="gist_show_rev", pattern="/gists/{gist_id}/rev/{revision}") config.add_view( GistView, - attr='gist_show', - route_name='gist_show_rev', request_method='GET', - renderer='rhodecode:templates/admin/gists/gist_show.mako') + attr="gist_show", + route_name="gist_show_rev", + request_method="GET", + renderer="rhodecode:templates/admin/gists/gist_show.mako", + ) - config.add_route( - name='gist_show_formatted', - pattern='/gists/{gist_id}/rev/{revision}/{format}') + config.add_route(name="gist_show_formatted", pattern="/gists/{gist_id}/rev/{revision}/{format}") + config.add_view(GistView, attr="gist_show", route_name="gist_show_formatted", request_method="GET", renderer=None) + + config.add_route(name="gist_show_formatted_path", pattern="/gists/{gist_id}/rev/{revision}/{format}/{f_path:.*}") + config.add_view( + GistView, attr="gist_show", route_name="gist_show_formatted_path", request_method="GET", renderer=None + ) + + config.add_route(name="gist_delete", pattern="/gists/{gist_id}/delete") + config.add_view(GistView, attr="gist_delete", route_name="gist_delete", request_method="POST") + + config.add_route(name="gist_edit", pattern="/gists/{gist_id}/edit") config.add_view( GistView, - attr='gist_show', - route_name='gist_show_formatted', request_method='GET', - renderer=None) + attr="gist_edit", + route_name="gist_edit", + request_method="GET", + renderer="rhodecode:templates/admin/gists/gist_edit.mako", + ) - config.add_route( - name='gist_show_formatted_path', - pattern='/gists/{gist_id}/rev/{revision}/{format}/{f_path:.*}') + config.add_route(name="gist_update", pattern="/gists/{gist_id}/update") config.add_view( GistView, - attr='gist_show', - route_name='gist_show_formatted_path', request_method='GET', - renderer=None) + attr="gist_update", + route_name="gist_update", + request_method="POST", + renderer="rhodecode:templates/admin/gists/gist_edit.mako", + ) - config.add_route( - name='gist_delete', pattern='/gists/{gist_id}/delete') + config.add_route(name="gist_edit_check_revision", pattern="/gists/{gist_id}/edit/check_revision") config.add_view( GistView, - attr='gist_delete', - route_name='gist_delete', request_method='POST') - - config.add_route( - name='gist_edit', pattern='/gists/{gist_id}/edit') - config.add_view( - GistView, - attr='gist_edit', - route_name='gist_edit', request_method='GET', - renderer='rhodecode:templates/admin/gists/gist_edit.mako') - - config.add_route( - name='gist_update', pattern='/gists/{gist_id}/update') - config.add_view( - GistView, - attr='gist_update', - route_name='gist_update', request_method='POST', - renderer='rhodecode:templates/admin/gists/gist_edit.mako') - - config.add_route( - name='gist_edit_check_revision', - pattern='/gists/{gist_id}/edit/check_revision') - config.add_view( - GistView, - attr='gist_edit_check_revision', - route_name='gist_edit_check_revision', request_method='GET', - renderer='json_ext') + attr="gist_edit_check_revision", + route_name="gist_edit_check_revision", + request_method="GET", + renderer="json_ext", + ) def includeme(config): diff --git a/rhodecode/apps/gist/tests/test_admin_gists.py b/rhodecode/apps/gist/tests/test_admin_gists.py index c97aa962..af26eaee 100644 --- a/rhodecode/apps/gist/tests/test_admin_gists.py +++ b/rhodecode/apps/gist/tests/test_admin_gists.py @@ -24,27 +24,39 @@ from rhodecode.model.db import User, Gist from rhodecode.model.gist import GistModel from rhodecode.model.meta import Session from rhodecode.tests import ( - TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, - TestController, assert_session_flash) + TEST_USER_ADMIN_LOGIN, + TEST_USER_REGULAR_LOGIN, + TEST_USER_REGULAR_PASS, + TestController, + assert_session_flash, +) from rhodecode.tests.routes import route_path class GistUtility(object): - def __init__(self): self._gist_ids = [] def __call__( - self, f_name: bytes, content: bytes = b'some gist', lifetime=-1, - description='gist-desc', gist_type='public', - acl_level=Gist.GIST_PUBLIC, owner=TEST_USER_ADMIN_LOGIN): - gist_mapping = { - f_name: {'content': content} - } + self, + f_name: bytes, + content: bytes = b"some gist", + lifetime=-1, + description="gist-desc", + gist_type="public", + acl_level=Gist.GIST_PUBLIC, + owner=TEST_USER_ADMIN_LOGIN, + ): + gist_mapping = {f_name: {"content": content}} user = User.get_by_username(owner) gist = GistModel().create( - description, owner=user, gist_mapping=gist_mapping, - gist_type=gist_type, lifetime=lifetime, gist_acl_level=acl_level) + description, + owner=user, + gist_mapping=gist_mapping, + gist_type=gist_type, + lifetime=lifetime, + gist_acl_level=acl_level, + ) Session().commit() self._gist_ids.append(gist.gist_id) return gist @@ -66,24 +78,23 @@ def create_gist(request): class TestGistsController(TestController): - def test_index_empty(self, create_gist): self.log_user() - response = self.app.get(route_path('gists_show')) - response.mustcontain('var gist_data = [];') + response = self.app.get(route_path("gists_show")) + response.mustcontain("var gist_data = [];") def test_index(self, create_gist): self.log_user() - g1 = create_gist(b'gist1') - g2 = create_gist(b'gist2', lifetime=1400) - g3 = create_gist(b'gist3', description='gist3-desc') - g4 = create_gist(b'gist4', gist_type='private').gist_access_id - response = self.app.get(route_path('gists_show')) + g1 = create_gist(b"gist1") + g2 = create_gist(b"gist2", lifetime=1400) + g3 = create_gist(b"gist3", description="gist3-desc") + g4 = create_gist(b"gist4", gist_type="private").gist_access_id + response = self.app.get(route_path("gists_show")) response.mustcontain(g1.gist_access_id) response.mustcontain(g2.gist_access_id) response.mustcontain(g3.gist_access_id) - response.mustcontain('gist3-desc') + response.mustcontain("gist3-desc") response.mustcontain(no=[g4]) # Expiration information should be visible @@ -92,20 +103,20 @@ class TestGistsController(TestController): def test_index_private_gists(self, create_gist): self.log_user() - gist = create_gist(b'gist5', gist_type='private') - response = self.app.get(route_path('gists_show', params=dict(private=1))) + gist = create_gist(b"gist5", gist_type="private") + response = self.app.get(route_path("gists_show", params=dict(private=1))) # and privates response.mustcontain(gist.gist_access_id) def test_index_show_all(self, create_gist): self.log_user() - create_gist(b'gist1') - create_gist(b'gist2', lifetime=1400) - create_gist(b'gist3', description='gist3-desc') - create_gist(b'gist4', gist_type='private') + create_gist(b"gist1") + create_gist(b"gist2", lifetime=1400) + create_gist(b"gist3", description="gist3-desc") + create_gist(b"gist4", gist_type="private") - response = self.app.get(route_path('gists_show', params=dict(all=1))) + response = self.app.get(route_path("gists_show", params=dict(all=1))) assert len(GistModel.get_all()) == 4 # and privates @@ -114,11 +125,11 @@ class TestGistsController(TestController): def test_index_show_all_hidden_from_regular(self, create_gist): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - create_gist(b'gist2', gist_type='private') - create_gist(b'gist3', gist_type='private') - create_gist(b'gist4', gist_type='private') + create_gist(b"gist2", gist_type="private") + create_gist(b"gist3", gist_type="private") + create_gist(b"gist4", gist_type="private") - response = self.app.get(route_path('gists_show', params=dict(all=1))) + response = self.app.get(route_path("gists_show", params=dict(all=1))) assert len(GistModel.get_all()) == 3 # since we don't have access to private in this view, we @@ -129,237 +140,238 @@ class TestGistsController(TestController): def test_create(self): self.log_user() response = self.app.post( - route_path('gists_create'), - params={'lifetime': -1, - 'content': 'gist test', - 'filename': 'foo', - 'gist_type': 'public', - 'gist_acl_level': Gist.ACL_LEVEL_PUBLIC, - 'csrf_token': self.csrf_token}, - status=302) + route_path("gists_create"), + params={ + "lifetime": -1, + "content": "gist test", + "filename": "foo", + "gist_type": "public", + "gist_acl_level": Gist.ACL_LEVEL_PUBLIC, + "csrf_token": self.csrf_token, + }, + status=302, + ) response = response.follow() - response.mustcontain('added file: foo') - response.mustcontain('gist test') + response.mustcontain("added file: foo") + response.mustcontain("gist test") def test_create_with_path_with_dirs(self): self.log_user() response = self.app.post( - route_path('gists_create'), - params={'lifetime': -1, - 'content': 'gist test', - 'filename': '/home/foo', - 'gist_type': 'public', - 'gist_acl_level': Gist.ACL_LEVEL_PUBLIC, - 'csrf_token': self.csrf_token}, - status=200) - response.mustcontain('Filename /home/foo cannot be inside a directory') + route_path("gists_create"), + params={ + "lifetime": -1, + "content": "gist test", + "filename": "/home/foo", + "gist_type": "public", + "gist_acl_level": Gist.ACL_LEVEL_PUBLIC, + "csrf_token": self.csrf_token, + }, + status=200, + ) + response.mustcontain("Filename /home/foo cannot be inside a directory") def test_access_expired_gist(self, create_gist): self.log_user() - gist = create_gist(b'never-see-me') + gist = create_gist(b"never-see-me") gist.gist_expires = 0 # 1970 Session().add(gist) Session().commit() - self.app.get(route_path('gist_show', gist_id=gist.gist_access_id), - status=404) + self.app.get(route_path("gist_show", gist_id=gist.gist_access_id), status=404) def test_create_private(self): self.log_user() response = self.app.post( - route_path('gists_create'), - params={'lifetime': -1, - 'content': 'private gist test', - 'filename': 'private-foo', - 'gist_type': 'private', - 'gist_acl_level': Gist.ACL_LEVEL_PUBLIC, - 'csrf_token': self.csrf_token}, - status=302) + route_path("gists_create"), + params={ + "lifetime": -1, + "content": "private gist test", + "filename": "private-foo", + "gist_type": "private", + "gist_acl_level": Gist.ACL_LEVEL_PUBLIC, + "csrf_token": self.csrf_token, + }, + status=302, + ) response = response.follow() - response.mustcontain('added file: private-foo<') - response.mustcontain('private gist test') - response.mustcontain('Private Gist') + response.mustcontain("added file: private-foo<") + response.mustcontain("private gist test") + response.mustcontain("Private Gist") # Make sure private gists are not indexed by robots - response.mustcontain( - '') + response.mustcontain('') def test_create_private_acl_private(self): self.log_user() response = self.app.post( - route_path('gists_create'), - params={'lifetime': -1, - 'content': 'private gist test', - 'filename': 'private-foo', - 'gist_type': 'private', - 'gist_acl_level': Gist.ACL_LEVEL_PRIVATE, - 'csrf_token': self.csrf_token}, - status=302) + route_path("gists_create"), + params={ + "lifetime": -1, + "content": "private gist test", + "filename": "private-foo", + "gist_type": "private", + "gist_acl_level": Gist.ACL_LEVEL_PRIVATE, + "csrf_token": self.csrf_token, + }, + status=302, + ) response = response.follow() - response.mustcontain('added file: private-foo<') - response.mustcontain('private gist test') - response.mustcontain('Private Gist') + response.mustcontain("added file: private-foo<") + response.mustcontain("private gist test") + response.mustcontain("Private Gist") # Make sure private gists are not indexed by robots - response.mustcontain( - '') + response.mustcontain('') def test_create_with_description(self): self.log_user() response = self.app.post( - route_path('gists_create'), - params={'lifetime': -1, - 'content': 'gist test', - 'filename': 'foo-desc', - 'description': 'gist-desc', - 'gist_type': 'public', - 'gist_acl_level': Gist.ACL_LEVEL_PUBLIC, - 'csrf_token': self.csrf_token}, - status=302) + route_path("gists_create"), + params={ + "lifetime": -1, + "content": "gist test", + "filename": "foo-desc", + "description": "gist-desc", + "gist_type": "public", + "gist_acl_level": Gist.ACL_LEVEL_PUBLIC, + "csrf_token": self.csrf_token, + }, + status=302, + ) response = response.follow() - response.mustcontain('added file: foo-desc') - response.mustcontain('gist test') - response.mustcontain('gist-desc') + response.mustcontain("added file: foo-desc") + response.mustcontain("gist test") + response.mustcontain("gist-desc") def test_create_public_with_anonymous_access(self): self.log_user() params = { - 'lifetime': -1, - 'content': 'gist test', - 'filename': 'foo-desc', - 'description': 'gist-desc', - 'gist_type': 'public', - 'gist_acl_level': Gist.ACL_LEVEL_PUBLIC, - 'csrf_token': self.csrf_token + "lifetime": -1, + "content": "gist test", + "filename": "foo-desc", + "description": "gist-desc", + "gist_type": "public", + "gist_acl_level": Gist.ACL_LEVEL_PUBLIC, + "csrf_token": self.csrf_token, } - response = self.app.post( - route_path('gists_create'), params=params, status=302) + response = self.app.post(route_path("gists_create"), params=params, status=302) self.logout_user() response = response.follow() - response.mustcontain('added file: foo-desc') - response.mustcontain('gist test') - response.mustcontain('gist-desc') + response.mustcontain("added file: foo-desc") + response.mustcontain("gist test") + response.mustcontain("gist-desc") def test_new(self): self.log_user() - self.app.get(route_path('gists_new')) + self.app.get(route_path("gists_new")) def test_delete(self, create_gist): self.log_user() - gist = create_gist(b'delete-me') + gist = create_gist(b"delete-me") response = self.app.post( - route_path('gist_delete', gist_id=gist.gist_id), - params={'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Deleted gist %s' % gist.gist_id) + route_path("gist_delete", gist_id=gist.gist_id), params={"csrf_token": self.csrf_token} + ) + assert_session_flash(response, "Deleted gist %s" % gist.gist_id) def test_delete_normal_user_his_gist(self, create_gist): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - gist = create_gist(b'delete-me', owner=TEST_USER_REGULAR_LOGIN) + gist = create_gist(b"delete-me", owner=TEST_USER_REGULAR_LOGIN) response = self.app.post( - route_path('gist_delete', gist_id=gist.gist_id), - params={'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Deleted gist %s' % gist.gist_id) + route_path("gist_delete", gist_id=gist.gist_id), params={"csrf_token": self.csrf_token} + ) + assert_session_flash(response, "Deleted gist %s" % gist.gist_id) def test_delete_normal_user_not_his_own_gist(self, create_gist): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - gist = create_gist(b'delete-me-2') + gist = create_gist(b"delete-me-2") self.app.post( - route_path('gist_delete', gist_id=gist.gist_id), - params={'csrf_token': self.csrf_token}, status=404) + route_path("gist_delete", gist_id=gist.gist_id), params={"csrf_token": self.csrf_token}, status=404 + ) def test_show(self, create_gist): - gist = create_gist(b'gist-show-me') - response = self.app.get(route_path('gist_show', gist_id=gist.gist_access_id)) + gist = create_gist(b"gist-show-me") + response = self.app.get(route_path("gist_show", gist_id=gist.gist_access_id)) - response.mustcontain('added file: gist-show-me<') + response.mustcontain("added file: gist-show-me<") assert_response = response.assert_response() - assert_response.element_equals_to( - 'div.rc-user span.user', - 'test_admin') + assert_response.element_equals_to("div.rc-user span.user", 'test_admin') - response.mustcontain('gist-desc') + response.mustcontain("gist-desc") def test_show_without_hg(self, create_gist): - with mock.patch( - 'rhodecode.lib.vcs.settings.ALIASES', ['git']): - gist = create_gist(b'gist-show-me-again') - self.app.get( - route_path('gist_show', gist_id=gist.gist_access_id), status=200) + with mock.patch("rhodecode.lib.vcs.settings.ALIASES", ["git"]): + gist = create_gist(b"gist-show-me-again") + self.app.get(route_path("gist_show", gist_id=gist.gist_access_id), status=200) def test_show_acl_private(self, create_gist): - gist = create_gist(b'gist-show-me-only-when-im-logged-in', - acl_level=Gist.ACL_LEVEL_PRIVATE) - self.app.get( - route_path('gist_show', gist_id=gist.gist_access_id), status=404) + gist = create_gist(b"gist-show-me-only-when-im-logged-in", acl_level=Gist.ACL_LEVEL_PRIVATE) + self.app.get(route_path("gist_show", gist_id=gist.gist_access_id), status=404) # now we log-in we should see thi gist self.log_user() - response = self.app.get( - route_path('gist_show', gist_id=gist.gist_access_id)) - response.mustcontain('added file: gist-show-me-only-when-im-logged-in') + response = self.app.get(route_path("gist_show", gist_id=gist.gist_access_id)) + response.mustcontain("added file: gist-show-me-only-when-im-logged-in") assert_response = response.assert_response() - assert_response.element_equals_to( - 'div.rc-user span.user', - 'test_admin') - response.mustcontain('gist-desc') + assert_response.element_equals_to("div.rc-user span.user", 'test_admin') + response.mustcontain("gist-desc") def test_show_as_raw(self, create_gist): - gist = create_gist(b'gist-show-me', content=b'GIST CONTENT') + gist = create_gist(b"gist-show-me", content=b"GIST CONTENT") response = self.app.get( - route_path('gist_show_formatted', - gist_id=gist.gist_access_id, revision='tip', - format='raw')) - assert response.text == 'GIST CONTENT' + route_path("gist_show_formatted", gist_id=gist.gist_access_id, revision="tip", format="raw") + ) + assert response.text == "GIST CONTENT" def test_show_as_raw_individual_file(self, create_gist): - gist = create_gist(b'gist-show-me-raw', content=b'GIST BODY') + gist = create_gist(b"gist-show-me-raw", content=b"GIST BODY") response = self.app.get( - route_path('gist_show_formatted_path', - gist_id=gist.gist_access_id, format='raw', - revision='tip', f_path='gist-show-me-raw')) - assert response.text == 'GIST BODY' + route_path( + "gist_show_formatted_path", + gist_id=gist.gist_access_id, + format="raw", + revision="tip", + f_path="gist-show-me-raw", + ) + ) + assert response.text == "GIST BODY" def test_edit_page(self, create_gist): self.log_user() - gist = create_gist(b'gist-for-edit', content=b'GIST EDIT BODY') - response = self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id)) - response.mustcontain('GIST EDIT BODY') + gist = create_gist(b"gist-for-edit", content=b"GIST EDIT BODY") + response = self.app.get(route_path("gist_edit", gist_id=gist.gist_access_id)) + response.mustcontain("GIST EDIT BODY") def test_edit_page_non_logged_user(self, create_gist): - gist = create_gist(b'gist-for-edit', content=b'GIST EDIT BODY') - self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id), - status=302) + gist = create_gist(b"gist-for-edit", content=b"GIST EDIT BODY") + self.app.get(route_path("gist_edit", gist_id=gist.gist_access_id), status=302) def test_edit_normal_user_his_gist(self, create_gist): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - gist = create_gist(b'gist-for-edit', owner=TEST_USER_REGULAR_LOGIN) - self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id, - status=200)) + gist = create_gist(b"gist-for-edit", owner=TEST_USER_REGULAR_LOGIN) + self.app.get(route_path("gist_edit", gist_id=gist.gist_access_id, status=200)) def test_edit_normal_user_not_his_own_gist(self, create_gist): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - gist = create_gist(b'delete-me') - self.app.get(route_path('gist_edit', gist_id=gist.gist_access_id), - status=404) + gist = create_gist(b"delete-me") + self.app.get(route_path("gist_edit", gist_id=gist.gist_access_id), status=404) def test_user_first_name_is_escaped(self, user_util, create_gist): - xss_atack_string = '">' + xss_atack_string = "\">" xss_escaped_string = h.html_escape(h.escape(xss_atack_string)) - password = 'test' - user = user_util.create_user( - firstname=xss_atack_string, password=password) - create_gist(b'gist', gist_type='public', owner=user.username) - response = self.app.get(route_path('gists_show')) + password = "test" + user = user_util.create_user(firstname=xss_atack_string, password=password) + create_gist(b"gist", gist_type="public", owner=user.username) + response = self.app.get(route_path("gists_show")) response.mustcontain(xss_escaped_string) def test_user_last_name_is_escaped(self, user_util, create_gist): - xss_atack_string = '">' + xss_atack_string = "\">" xss_escaped_string = h.html_escape(h.escape(xss_atack_string)) - password = 'test' - user = user_util.create_user( - lastname=xss_atack_string, password=password) - create_gist(b'gist', gist_type='public', owner=user.username) - response = self.app.get(route_path('gists_show')) + password = "test" + user = user_util.create_user(lastname=xss_atack_string, password=password) + create_gist(b"gist", gist_type="public", owner=user.username) + response = self.app.get(route_path("gists_show")) response.mustcontain(xss_escaped_string) diff --git a/rhodecode/apps/gist/views.py b/rhodecode/apps/gist/views.py index 48aeb978..5456f232 100644 --- a/rhodecode/apps/gist/views.py +++ b/rhodecode/apps/gist/views.py @@ -44,24 +44,23 @@ log = logging.getLogger(__name__) class GistView(BaseAppView): - def load_default_context(self): _ = self.request.translate c = self._get_local_tmpl_context() c.user = c.auth_user.get_instance() c.lifetime_values = [ - (-1, _('forever')), - (5, _('5 minutes')), - (60, _('1 hour')), - (60 * 24, _('1 day')), - (60 * 24 * 30, _('1 month')), + (-1, _("forever")), + (5, _("5 minutes")), + (60, _("1 hour")), + (60 * 24, _("1 day")), + (60 * 24 * 30, _("1 month")), ] c.lifetime_options = [(c.lifetime_values, _("Lifetime"))] c.acl_options = [ (Gist.ACL_LEVEL_PRIVATE, _("Requires registered account")), - (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users")) + (Gist.ACL_LEVEL_PUBLIC, _("Can be accessed by anonymous users")), ] return c @@ -71,57 +70,63 @@ class GistView(BaseAppView): c = self.load_default_context() not_default_user = self._rhodecode_user.username != User.DEFAULT_USER - c.show_private = self.request.GET.get('private') and not_default_user - c.show_public = self.request.GET.get('public') and not_default_user - c.show_all = self.request.GET.get('all') and self._rhodecode_user.admin + c.show_private = self.request.GET.get("private") and not_default_user + c.show_public = self.request.GET.get("public") and not_default_user + c.show_all = self.request.GET.get("all") and self._rhodecode_user.admin - gists = _gists = Gist().query()\ - .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time()))\ + gists = _gists = ( + Gist() + .query() + .filter(or_(Gist.gist_expires == -1, Gist.gist_expires >= time.time())) .order_by(Gist.created_on.desc()) + ) - c.active = 'public' + c.active = "public" # MY private if c.show_private and not c.show_public: - gists = _gists.filter(Gist.gist_type == Gist.GIST_PRIVATE)\ - .filter(Gist.gist_owner == self._rhodecode_user.user_id) - c.active = 'my_private' + gists = _gists.filter(Gist.gist_type == Gist.GIST_PRIVATE).filter( + Gist.gist_owner == self._rhodecode_user.user_id + ) + c.active = "my_private" # MY public elif c.show_public and not c.show_private: - gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC)\ - .filter(Gist.gist_owner == self._rhodecode_user.user_id) - c.active = 'my_public' + gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC).filter( + Gist.gist_owner == self._rhodecode_user.user_id + ) + c.active = "my_public" # MY public+private elif c.show_private and c.show_public: - gists = _gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC, - Gist.gist_type == Gist.GIST_PRIVATE))\ - .filter(Gist.gist_owner == self._rhodecode_user.user_id) - c.active = 'my_all' + gists = _gists.filter(or_(Gist.gist_type == Gist.GIST_PUBLIC, Gist.gist_type == Gist.GIST_PRIVATE)).filter( + Gist.gist_owner == self._rhodecode_user.user_id + ) + c.active = "my_all" # Show all by super-admin elif c.show_all: - c.active = 'all' + c.active = "all" gists = _gists # default show ALL public gists if not c.show_public and not c.show_private and not c.show_all: gists = _gists.filter(Gist.gist_type == Gist.GIST_PUBLIC) - c.active = 'public' + c.active = "public" - _render = self.request.get_partial_renderer( - 'rhodecode:templates/data_table/_dt_elements.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/data_table/_dt_elements.mako") data = [] for gist in gists: - data.append({ - 'created_on': _render('gist_created', gist.created_on), - 'created_on_raw': gist.created_on, - 'type': _render('gist_type', gist.gist_type), - 'access_id': _render('gist_access_id', gist.gist_access_id, gist.owner.full_contact), - 'author': _render('gist_author', gist.owner.full_contact, gist.created_on, gist.gist_expires), - 'author_raw': h.escape(gist.owner.full_contact), - 'expires': _render('gist_expires', gist.gist_expires), - 'description': _render('gist_description', gist.gist_description) - }) + data.append( + { + "created_on": _render("gist_created", gist.created_on), + "created_on_raw": gist.created_on, + "type": _render("gist_type", gist.gist_type), + "access_id": _render("gist_access_id", gist.gist_access_id, gist.owner.full_contact), + "author": _render("gist_author", gist.owner.full_contact, gist.created_on, gist.gist_expires), + "author_raw": h.escape(gist.owner.full_contact), + "expires": _render("gist_expires", gist.gist_expires), + "description": _render("gist_description", gist.gist_description), + } + ) c.data = ext_json.str_json(data) return self._get_template_context(c) @@ -141,31 +146,32 @@ class GistView(BaseAppView): data = dict(self.request.POST) - filename = data.pop('filename', '') or Gist.DEFAULT_FILENAME + filename = data.pop("filename", "") or Gist.DEFAULT_FILENAME - data['nodes'] = [{ - 'filename': filename, - 'content': data.pop('content', ''), - 'mimetype': data.pop('mimetype', None) # None is autodetect - }] + data["nodes"] = [ + { + "filename": filename, + "content": data.pop("content", ""), + "mimetype": data.pop("mimetype", None), # None is autodetect + } + ] - schema = gist_schema.GistSchema().bind( - lifetime_options=[x[0] for x in c.lifetime_values]) + schema = gist_schema.GistSchema().bind(lifetime_options=[x[0] for x in c.lifetime_values]) try: schema_data = schema.deserialize(data) # convert to safer format with just KEYs so we sure no duplicates - schema_data['nodes'] = gist_schema.sequence_to_nodes(schema_data['nodes']) + schema_data["nodes"] = gist_schema.sequence_to_nodes(schema_data["nodes"]) gist = GistModel().create( - gist_id=schema_data['gistid'], # custom access id not real ID - description=schema_data['description'], + gist_id=schema_data["gistid"], # custom access id not real ID + description=schema_data["description"], owner=self._rhodecode_user.user_id, - gist_mapping=schema_data['nodes'], - gist_type=schema_data['gist_type'], - lifetime=schema_data['lifetime'], - gist_acl_level=schema_data['gist_acl_level'] + gist_mapping=schema_data["nodes"], + gist_type=schema_data["gist_type"], + lifetime=schema_data["lifetime"], + gist_acl_level=schema_data["gist_acl_level"], ) Session().commit() new_gist_id = gist.gist_access_id @@ -173,97 +179,85 @@ class GistView(BaseAppView): defaults = data errors = errors.asdict() - if 'nodes.0.content' in errors: - errors['content'] = errors['nodes.0.content'] - del errors['nodes.0.content'] - if 'nodes.0.filename' in errors: - errors['filename'] = errors['nodes.0.filename'] - del errors['nodes.0.filename'] + if "nodes.0.content" in errors: + errors["content"] = errors["nodes.0.content"] + del errors["nodes.0.content"] + if "nodes.0.filename" in errors: + errors["filename"] = errors["nodes.0.filename"] + del errors["nodes.0.filename"] - data = render('rhodecode:templates/admin/gists/gist_new.mako', - self._get_template_context(c), self.request) + data = render("rhodecode:templates/admin/gists/gist_new.mako", self._get_template_context(c), self.request) html = formencode.htmlfill.render( - data, - defaults=defaults, - errors=errors, - prefix_error=False, - encoding="UTF-8", - force_defaults=False + data, defaults=defaults, errors=errors, prefix_error=False, encoding="UTF-8", force_defaults=False ) return Response(html) except Exception: log.exception("Exception while trying to create a gist") - h.flash(_('Error occurred during gist creation'), category='error') - raise HTTPFound(h.route_url('gists_new')) - raise HTTPFound(h.route_url('gist_show', gist_id=new_gist_id)) + h.flash(_("Error occurred during gist creation"), category="error") + raise HTTPFound(h.route_url("gists_new")) + raise HTTPFound(h.route_url("gist_show", gist_id=new_gist_id)) @LoginRequired() @NotAnonymous() @CSRFRequired() def gist_delete(self): _ = self.request.translate - gist_id = self.request.matchdict['gist_id'] + gist_id = self.request.matchdict["gist_id"] c = self.load_default_context() c.gist = Gist.get_or_404(gist_id) owner = c.gist.gist_owner == self._rhodecode_user.user_id - if not (h.HasPermissionAny('hg.admin')() or owner): - log.warning('Deletion of Gist was forbidden ' - 'by unauthorized user: `%s`', self._rhodecode_user) + if not (h.HasPermissionAny("hg.admin")() or owner): + log.warning("Deletion of Gist was forbidden by unauthorized user: `%s`", self._rhodecode_user) raise HTTPNotFound() GistModel().delete(c.gist) Session().commit() - h.flash(_('Deleted gist %s') % c.gist.gist_access_id, category='success') + h.flash(_("Deleted gist %s") % c.gist.gist_access_id, category="success") - raise HTTPFound(h.route_url('gists_show')) + raise HTTPFound(h.route_url("gists_show")) def _get_gist(self, gist_id): - gist = Gist.get_or_404(gist_id) # Check if this gist is expired if gist.gist_expires != -1: if time.time() > gist.gist_expires: - log.error( - 'Gist expired at %s', time_to_datetime(gist.gist_expires)) + log.error("Gist expired at %s", time_to_datetime(gist.gist_expires)) raise HTTPNotFound() # check if this gist requires a login is_default_user = self._rhodecode_user.username == User.DEFAULT_USER if gist.acl_level == Gist.ACL_LEVEL_PRIVATE and is_default_user: - log.error("Anonymous user %s tried to access protected gist `%s`", - self._rhodecode_user, gist_id) + log.error("Anonymous user %s tried to access protected gist `%s`", self._rhodecode_user, gist_id) raise HTTPNotFound() return gist @LoginRequired() def gist_show(self): - gist_id = self.request.matchdict['gist_id'] + gist_id = self.request.matchdict["gist_id"] # TODO(marcink): expose those via matching dict - revision = self.request.matchdict.get('revision', 'tip') - f_path = self.request.matchdict.get('f_path', None) - return_format = self.request.matchdict.get('format') + revision = self.request.matchdict.get("revision", "tip") + f_path = self.request.matchdict.get("f_path", None) + return_format = self.request.matchdict.get("format") c = self.load_default_context() c.gist = self._get_gist(gist_id) - c.render = not self.request.GET.get('no-render', False) + c.render = not self.request.GET.get("no-render", False) try: - c.file_last_commit, c.files = GistModel().get_gist_files( - gist_id, revision=revision) + c.file_last_commit, c.files = GistModel().get_gist_files(gist_id, revision=revision) except VCSError: log.exception("Exception in gist show") raise HTTPNotFound() - if return_format == 'raw': - content = b'\n\n'.join([f.content for f in c.files - if (f_path is None or f.path == f_path)]) + if return_format == "raw": + content = b"\n\n".join([f.content for f in c.files if (f_path is None or f.path == f_path)]) response = Response(content) - response.content_type = 'text/plain' + response.content_type = "text/plain" return response elif return_format: raise HTTPBadRequest() @@ -274,12 +268,12 @@ class GistView(BaseAppView): @NotAnonymous() def gist_edit(self): _ = self.request.translate - gist_id = self.request.matchdict['gist_id'] + gist_id = self.request.matchdict["gist_id"] c = self.load_default_context() c.gist = self._get_gist(gist_id) owner = c.gist.gist_owner == self._rhodecode_user.user_id - if not (h.HasPermissionAny('hg.admin')() or owner): + if not (h.HasPermissionAny("hg.admin")() or owner): raise HTTPNotFound() try: @@ -289,14 +283,12 @@ class GistView(BaseAppView): raise HTTPNotFound() if c.gist.gist_expires == -1: - expiry = _('never') + expiry = _("never") else: # this cannot use timeago, since it's used in select2 as a value expiry = h.age(h.time_to_datetime(c.gist.gist_expires)) - c.lifetime_values.append( - (0, _('%(expiry)s - current value') % {'expiry': _(expiry)}) - ) + c.lifetime_values.append((0, _("%(expiry)s - current value") % {"expiry": _(expiry)})) return self._get_template_context(c) @@ -305,12 +297,12 @@ class GistView(BaseAppView): @CSRFRequired() def gist_update(self): _ = self.request.translate - gist_id = self.request.matchdict['gist_id'] + gist_id = self.request.matchdict["gist_id"] c = self.load_default_context() c.gist = self._get_gist(gist_id) owner = c.gist.gist_owner == self._rhodecode_user.user_id - if not (h.HasPermissionAny('hg.admin')() or owner): + if not (h.HasPermissionAny("hg.admin")() or owner): raise HTTPNotFound() data = peppercorn.parse(self.request.POST.items()) @@ -324,52 +316,48 @@ class GistView(BaseAppView): try: schema_data = schema.deserialize(data) # convert to safer format with just KEYs so we sure no duplicates - schema_data['nodes'] = gist_schema.sequence_to_nodes( - schema_data['nodes']) + schema_data["nodes"] = gist_schema.sequence_to_nodes(schema_data["nodes"]) GistModel().update( gist=c.gist, - description=schema_data['description'], + description=schema_data["description"], owner=c.gist.owner, - gist_mapping=schema_data['nodes'], - lifetime=schema_data['lifetime'], - gist_acl_level=schema_data['gist_acl_level'] + gist_mapping=schema_data["nodes"], + lifetime=schema_data["lifetime"], + gist_acl_level=schema_data["gist_acl_level"], ) Session().commit() - h.flash(_('Successfully updated gist content'), category='success') + h.flash(_("Successfully updated gist content"), category="success") except NodeNotChangedError: # raised if nothing was changed in repo itself. We anyway then # store only DB stuff for gist Session().commit() - h.flash(_('Successfully updated gist data'), category='success') + h.flash(_("Successfully updated gist data"), category="success") except validation_schema.Invalid as errors: errors = h.escape(errors.asdict()) - h.flash(_('Error occurred during update of gist {}: {}').format( - gist_id, errors), category='error') + h.flash(_("Error occurred during update of gist {}: {}").format(gist_id, errors), category="error") except Exception: log.exception("Exception in gist edit") - h.flash(_('Error occurred during update of gist %s') % gist_id, - category='error') + h.flash(_("Error occurred during update of gist %s") % gist_id, category="error") - raise HTTPFound(h.route_url('gist_show', gist_id=gist_id)) + raise HTTPFound(h.route_url("gist_show", gist_id=gist_id)) @LoginRequired() @NotAnonymous() def gist_edit_check_revision(self): _ = self.request.translate - gist_id = self.request.matchdict['gist_id'] + gist_id = self.request.matchdict["gist_id"] c = self.load_default_context() c.gist = self._get_gist(gist_id) last_rev = c.gist.scm_instance().get_commit() success = True - revision = self.request.GET.get('revision') + revision = self.request.GET.get("revision") if revision != last_rev.raw_id: - log.error('Last revision %s is different then submitted %s', - revision, last_rev) + log.error("Last revision %s is different then submitted %s", revision, last_rev) # our gist has newer version than we success = False - return {'success': success} + return {"success": success} diff --git a/rhodecode/apps/home/__init__.py b/rhodecode/apps/home/__init__.py index 77698ecf..ed1a0414 100644 --- a/rhodecode/apps/home/__init__.py +++ b/rhodecode/apps/home/__init__.py @@ -23,12 +23,12 @@ class VCSCallPredicate(object): self.val = val def text(self): - return f'vcs_call route = {self.val}' + return f"vcs_call route = {self.val}" phash = text def __call__(self, info, request): - if hasattr(request, 'vcs_call'): + if hasattr(request, "vcs_call"): # skip vcs calls return False @@ -37,109 +37,103 @@ class VCSCallPredicate(object): def includeme(config): from rhodecode.apps.home.views import HomeView - - config.add_route_predicate( - 'skip_vcs_call', VCSCallPredicate) - config.add_route( - name='home', - pattern='/') + config.add_route_predicate("skip_vcs_call", VCSCallPredicate) + + config.add_route(name="home", pattern="/") + config.add_view( + HomeView, attr="main_page", route_name="home", request_method="GET", renderer="rhodecode:templates/index.mako" + ) + + config.add_route(name="main_page_repos_data", pattern="/_home_repos") config.add_view( HomeView, - attr='main_page', - route_name='home', request_method='GET', - renderer='rhodecode:templates/index.mako') + attr="main_page_repos_data", + route_name="main_page_repos_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='main_page_repos_data', - pattern='/_home_repos') + config.add_route(name="main_page_repo_groups_data", pattern="/_home_repo_groups") config.add_view( HomeView, - attr='main_page_repos_data', - route_name='main_page_repos_data', - request_method='GET', renderer='json_ext', xhr=True) + attr="main_page_repo_groups_data", + route_name="main_page_repo_groups_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='main_page_repo_groups_data', - pattern='/_home_repo_groups') + config.add_route(name="user_autocomplete_data", pattern="/_users") config.add_view( HomeView, - attr='main_page_repo_groups_data', - route_name='main_page_repo_groups_data', - request_method='GET', renderer='json_ext', xhr=True) + attr="user_autocomplete_data", + route_name="user_autocomplete_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='user_autocomplete_data', - pattern='/_users') + config.add_route(name="user_group_autocomplete_data", pattern="/_user_groups") config.add_view( HomeView, - attr='user_autocomplete_data', - route_name='user_autocomplete_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="user_group_autocomplete_data", + route_name="user_group_autocomplete_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='user_group_autocomplete_data', - pattern='/_user_groups') + config.add_route(name="repo_list_data", pattern="/_repos") config.add_view( HomeView, - attr='user_group_autocomplete_data', - route_name='user_group_autocomplete_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="repo_list_data", + route_name="repo_list_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='repo_list_data', - pattern='/_repos') + config.add_route(name="repo_group_list_data", pattern="/_repo_groups") config.add_view( HomeView, - attr='repo_list_data', - route_name='repo_list_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="repo_group_list_data", + route_name="repo_group_list_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='repo_group_list_data', - pattern='/_repo_groups') + config.add_route(name="goto_switcher_data", pattern="/_goto_data") config.add_view( HomeView, - attr='repo_group_list_data', - route_name='repo_group_list_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="goto_switcher_data", + route_name="goto_switcher_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) - config.add_route( - name='goto_switcher_data', - pattern='/_goto_data') + config.add_route(name="markup_preview", pattern="/_markup_preview") + config.add_view( + HomeView, attr="markup_preview", route_name="markup_preview", request_method="POST", renderer="string", xhr=True + ) + + config.add_route(name="file_preview", pattern="/_file_preview") + config.add_view( + HomeView, attr="file_preview", route_name="file_preview", request_method="POST", renderer="string", xhr=True + ) + + config.add_route(name="store_user_session_value", pattern="/_store_session_attr") config.add_view( HomeView, - attr='goto_switcher_data', - route_name='goto_switcher_data', request_method='GET', - renderer='json_ext', xhr=True) - - config.add_route( - name='markup_preview', - pattern='/_markup_preview') - config.add_view( - HomeView, - attr='markup_preview', - route_name='markup_preview', request_method='POST', - renderer='string', xhr=True) - - config.add_route( - name='file_preview', - pattern='/_file_preview') - config.add_view( - HomeView, - attr='file_preview', - route_name='file_preview', request_method='POST', - renderer='string', xhr=True) - - config.add_route( - name='store_user_session_value', - pattern='/_store_session_attr') - config.add_view( - HomeView, - attr='store_user_session_attr', - route_name='store_user_session_value', request_method='POST', - renderer='string', xhr=True) + attr="store_user_session_attr", + route_name="store_user_session_value", + request_method="POST", + renderer="string", + xhr=True, + ) # register our static links via redirection mechanism routing_links.connect_redirection_links(config) - diff --git a/rhodecode/apps/home/tests/__init__.py b/rhodecode/apps/home/tests/__init__.py index af7abedc..7da336ac 100644 --- a/rhodecode/apps/home/tests/__init__.py +++ b/rhodecode/apps/home/tests/__init__.py @@ -23,30 +23,30 @@ def assert_and_get_main_filter_content(result): commits = [] users = [] for data_item in result: - assert data_item['id'] - assert data_item['value'] - assert data_item['value_display'] - assert data_item['url'] + assert data_item["id"] + assert data_item["value"] + assert data_item["value_display"] + assert data_item["url"] - if data_item['type'] == 'search': - display_val = data_item['value_display'] - if data_item['id'] == -1: - assert 'File content search for:' in display_val, display_val - elif data_item['id'] == -2: - assert 'Commit search for:' in display_val, display_val + if data_item["type"] == "search": + display_val = data_item["value_display"] + if data_item["id"] == -1: + assert "File content search for:" in display_val, display_val + elif data_item["id"] == -2: + assert "Commit search for:" in display_val, display_val else: - assert False, 'No Proper ID returned {}'.format(data_item['id']) + assert False, "No Proper ID returned {}".format(data_item["id"]) - elif data_item['type'] == 'repo': + elif data_item["type"] == "repo": repos.append(data_item) - elif data_item['type'] == 'repo_group': + elif data_item["type"] == "repo_group": groups.append(data_item) - elif data_item['type'] == 'user': + elif data_item["type"] == "user": users.append(data_item) - elif data_item['type'] == 'commit': + elif data_item["type"] == "commit": commits.append(data_item) else: - raise Exception('invalid type `%s`' % data_item['type']) + raise Exception("invalid type `%s`" % data_item["type"]) return repos, groups, users, commits @@ -54,14 +54,14 @@ def assert_and_get_main_filter_content(result): def assert_and_get_repo_list_content(result): repos = [] for data in result: - for data_item in data['children']: - assert data_item['id'] - assert data_item['text'] - assert data_item['url'] + for data_item in data["children"]: + assert data_item["id"] + assert data_item["text"] + assert data_item["url"] - if data_item['type'] == 'repo': + if data_item["type"] == "repo": repos.append(data_item) else: - raise Exception('invalid type %s' % data_item['type']) + raise Exception("invalid type %s" % data_item["type"]) return repos diff --git a/rhodecode/apps/home/tests/test_get_goto_switched_data.py b/rhodecode/apps/home/tests/test_get_goto_switched_data.py index 441e252e..36c34eb5 100644 --- a/rhodecode/apps/home/tests/test_get_goto_switched_data.py +++ b/rhodecode/apps/home/tests/test_get_goto_switched_data.py @@ -34,25 +34,24 @@ fixture = Fixture() class TestGotoSwitcherData(TestController): - required_repos_with_groups = [ - 'abc', - 'abc-fork', - 'forks/abcd', - 'abcd', - 'abcde', - 'a/abc', - 'aa/abc', - 'aaa/abc', - 'aaaa/abc', - 'repos_abc/aaa/abc', - 'abc_repos/abc', - 'abc_repos/abcd', - 'xxx/xyz', - 'forked-abc/a/abc' + "abc", + "abc-fork", + "forks/abcd", + "abcd", + "abcde", + "a/abc", + "aa/abc", + "aaa/abc", + "aaaa/abc", + "repos_abc/aaa/abc", + "abc_repos/abc", + "abc_repos/abcd", + "xxx/xyz", + "forked-abc/a/abc", ] - @pytest.fixture(autouse=True, scope='class') + @pytest.fixture(autouse=True, scope="class") def prepare(self, request, baseapp): for repo_and_group in self.required_repos_with_groups: # create structure of groups and return the last group @@ -60,8 +59,8 @@ class TestGotoSwitcherData(TestController): repo_group = map_groups(repo_and_group) RepoModel()._create_repo( - repo_and_group, 'hg', 'test-ac', TEST_USER_ADMIN_LOGIN, - repo_group=getattr(repo_group, 'group_id', None)) + repo_and_group, "hg", "test-ac", TEST_USER_ADMIN_LOGIN, repo_group=getattr(repo_group, "group_id", None) + ) Session().commit() @@ -77,8 +76,8 @@ class TestGotoSwitcherData(TestController): # then delete all empty groups for repo_and_groups in self.required_repos_with_groups: - if '/' in repo_and_groups: - r_group = repo_and_groups.rsplit('/', 1)[0] + if "/" in repo_and_groups: + r_group = repo_and_groups.rsplit("/", 1)[0] repo_group = RepoGroup.get_by_group_name(r_group) if not repo_group: continue @@ -93,10 +92,8 @@ class TestGotoSwitcherData(TestController): def test_empty_query(self, xhr_header): self.log_user() - response = self.app.get( - route_path('goto_switcher_data'), - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['suggestions'] + response = self.app.get(route_path("goto_switcher_data"), extra_environ=xhr_header, status=200) + result = json.loads(response.body)["suggestions"] assert result == [] @@ -104,10 +101,9 @@ class TestGotoSwitcherData(TestController): self.log_user() response = self.app.get( - route_path('goto_switcher_data'), - params={'query': 'abc'}, - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['suggestions'] + route_path("goto_switcher_data"), params={"query": "abc"}, extra_environ=xhr_header, status=200 + ) + result = json.loads(response.body)["suggestions"] repos, groups, users, commits = assert_and_get_main_filter_content(result) @@ -120,10 +116,9 @@ class TestGotoSwitcherData(TestController): self.log_user() response = self.app.get( - route_path('goto_switcher_data'), - params={'query': 'user:admin'}, - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['suggestions'] + route_path("goto_switcher_data"), params={"query": "user:admin"}, extra_environ=xhr_header, status=200 + ) + result = json.loads(response.body)["suggestions"] repos, groups, users, commits = assert_and_get_main_filter_content(result) @@ -136,10 +131,9 @@ class TestGotoSwitcherData(TestController): self.log_user() response = self.app.get( - route_path('goto_switcher_data'), - params={'query': 'commit:e8'}, - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['suggestions'] + route_path("goto_switcher_data"), params={"query": "commit:e8"}, extra_environ=xhr_header, status=200 + ) + result = json.loads(response.body)["suggestions"] repos, groups, users, commits = assert_and_get_main_filter_content(result) @@ -152,16 +146,14 @@ class TestGotoSwitcherData(TestController): self.log_user() response = self.app.get( - route_path('goto_switcher_data'), - params={'query': 'abc'}, - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['suggestions'] + route_path("goto_switcher_data"), params={"query": "abc"}, extra_environ=xhr_header, status=200 + ) + result = json.loads(response.body)["suggestions"] repos, groups, users, commits = assert_and_get_main_filter_content(result) - test_repos = [x['value_display'] for x in repos[:4]] - assert ['abc', 'abcd', 'a/abc', 'abcde'] == test_repos + test_repos = [x["value_display"] for x in repos[:4]] + assert ["abc", "abcd", "a/abc", "abcde"] == test_repos - test_groups = [x['value_display'] for x in groups[:4]] - assert ['abc_repos', 'repos_abc', - 'forked-abc', 'forked-abc/a'] == test_groups + test_groups = [x["value_display"] for x in groups[:4]] + assert ["abc_repos", "repos_abc", "forked-abc", "forked-abc/a"] == test_groups diff --git a/rhodecode/apps/home/tests/test_get_repo_list_data.py b/rhodecode/apps/home/tests/test_get_repo_list_data.py index 0bc68cee..eff18caf 100644 --- a/rhodecode/apps/home/tests/test_get_repo_list_data.py +++ b/rhodecode/apps/home/tests/test_get_repo_list_data.py @@ -29,14 +29,11 @@ fixture = Fixture() class TestRepoListData(TestController): - def test_returns_list_of_repos_and_groups(self, xhr_header): self.log_user() - response = self.app.get( - route_path('repo_list_data'), - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['results'] + response = self.app.get(route_path("repo_list_data"), extra_environ=xhr_header, status=200) + result = json.loads(response.body)["results"] repos = assert_and_get_repo_list_content(result) @@ -46,37 +43,38 @@ class TestRepoListData(TestController): self.log_user() response = self.app.get( - route_path('repo_list_data'), - params={'query': 'vcs_test_git'}, - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['results'] + route_path("repo_list_data"), params={"query": "vcs_test_git"}, extra_environ=xhr_header, status=200 + ) + result = json.loads(response.body)["results"] repos = assert_and_get_repo_list_content(result) - assert len(repos) == len(Repository.query().filter( - Repository.repo_name.ilike('%vcs_test_git%')).all()) + assert len(repos) == len(Repository.query().filter(Repository.repo_name.ilike("%vcs_test_git%")).all()) def test_returns_list_of_repos_and_groups_filtered_with_type(self, xhr_header): self.log_user() response = self.app.get( - route_path('repo_list_data'), - params={'query': 'vcs_test_git', 'repo_type': 'git'}, - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['results'] + route_path("repo_list_data"), + params={"query": "vcs_test_git", "repo_type": "git"}, + extra_environ=xhr_header, + status=200, + ) + result = json.loads(response.body)["results"] repos = assert_and_get_repo_list_content(result) - assert len(repos) == len(Repository.query().filter( - Repository.repo_name.ilike('%vcs_test_git%')).all()) + assert len(repos) == len(Repository.query().filter(Repository.repo_name.ilike("%vcs_test_git%")).all()) def test_returns_list_of_repos_non_ascii_query(self, xhr_header): self.log_user() response = self.app.get( - route_path('repo_list_data'), - params={'query': 'ć_vcs_test_ą', 'repo_type': 'git'}, - extra_environ=xhr_header, status=200) - result = json.loads(response.body)['results'] + route_path("repo_list_data"), + params={"query": "ć_vcs_test_ą", "repo_type": "git"}, + extra_environ=xhr_header, + status=200, + ) + result = json.loads(response.body)["results"] repos = assert_and_get_repo_list_content(result) diff --git a/rhodecode/apps/home/tests/test_get_user_data.py b/rhodecode/apps/home/tests/test_get_user_data.py index 6017f0c0..c94a744b 100644 --- a/rhodecode/apps/home/tests/test_get_user_data.py +++ b/rhodecode/apps/home/tests/test_get_user_data.py @@ -27,71 +27,70 @@ fixture = Fixture() class TestUserAutocompleteData(TestController): - def test_returns_list_of_users(self, user_util, xhr_header): self.log_user() user = user_util.create_user(active=True) user_name = user.username - response = self.app.get( - route_path('user_autocomplete_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("user_autocomplete_data"), extra_environ=xhr_header, status=200) result = json.loads(response.body) - values = [suggestion['value'] for suggestion in result['suggestions']] + values = [suggestion["value"] for suggestion in result["suggestions"]] assert user_name in values - def test_returns_inactive_users_when_active_flag_sent( - self, user_util, xhr_header): + def test_returns_inactive_users_when_active_flag_sent(self, user_util, xhr_header): self.log_user() user = user_util.create_user(active=False) user_name = user.username response = self.app.get( - route_path('user_autocomplete_data', - params=dict(user_groups='true', active='0')), - extra_environ=xhr_header, status=200) + route_path("user_autocomplete_data", params=dict(user_groups="true", active="0")), + extra_environ=xhr_header, + status=200, + ) result = json.loads(response.body) - values = [suggestion['value'] for suggestion in result['suggestions']] + values = [suggestion["value"] for suggestion in result["suggestions"]] assert user_name in values response = self.app.get( - route_path('user_autocomplete_data', - params=dict(user_groups='true', active='1')), - extra_environ=xhr_header, status=200) + route_path("user_autocomplete_data", params=dict(user_groups="true", active="1")), + extra_environ=xhr_header, + status=200, + ) result = json.loads(response.body) - values = [suggestion['value'] for suggestion in result['suggestions']] + values = [suggestion["value"] for suggestion in result["suggestions"]] assert user_name not in values - def test_returns_groups_when_user_groups_flag_sent( - self, user_util, xhr_header): + def test_returns_groups_when_user_groups_flag_sent(self, user_util, xhr_header): self.log_user() group = user_util.create_user_group(user_groups_active=True) group_name = group.users_group_name response = self.app.get( - route_path('user_autocomplete_data', - params=dict(user_groups='true')), - extra_environ=xhr_header, status=200) + route_path("user_autocomplete_data", params=dict(user_groups="true")), extra_environ=xhr_header, status=200 + ) result = json.loads(response.body) - values = [suggestion['value'] for suggestion in result['suggestions']] + values = [suggestion["value"] for suggestion in result["suggestions"]] assert group_name in values - @pytest.mark.parametrize('query, count', [ - ('hello1', 0), - ('dev', 2), - ]) - def test_result_is_limited_when_query_is_sent(self, user_util, xhr_header, - query, count): + @pytest.mark.parametrize( + "query, count", + [ + ("hello1", 0), + ("dev", 2), + ], + ) + def test_result_is_limited_when_query_is_sent(self, user_util, xhr_header, query, count): self.log_user() - user_util._test_name = 'dev-test' + user_util._test_name = "dev-test" user_util.create_user() - user_util._test_name = 'dev-group-test' + user_util._test_name = "dev-group-test" user_util.create_user_group() response = self.app.get( - route_path('user_autocomplete_data', - params=dict(user_groups='true', query=query)), - extra_environ=xhr_header, status=200) + route_path("user_autocomplete_data", params=dict(user_groups="true", query=query)), + extra_environ=xhr_header, + status=200, + ) result = json.loads(response.body) - assert len(result['suggestions']) == count + assert len(result["suggestions"]) == count diff --git a/rhodecode/apps/home/tests/test_get_user_group_data.py b/rhodecode/apps/home/tests/test_get_user_group_data.py index 73761538..b86f145b 100644 --- a/rhodecode/apps/home/tests/test_get_user_group_data.py +++ b/rhodecode/apps/home/tests/test_get_user_group_data.py @@ -28,56 +28,53 @@ fixture = Fixture() class TestUserGroupAutocompleteData(TestController): - def test_returns_list_of_user_groups(self, user_util, xhr_header): self.log_user() user_group = user_util.create_user_group(active=True) user_group_name = user_group.users_group_name - response = self.app.get( - route_path('user_group_autocomplete_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("user_group_autocomplete_data"), extra_environ=xhr_header, status=200) result = json.loads(response.body) - values = [suggestion['value'] for suggestion in result['suggestions']] + values = [suggestion["value"] for suggestion in result["suggestions"]] assert user_group_name in values - def test_returns_inactive_user_groups_when_active_flag_sent( - self, user_util, xhr_header): + def test_returns_inactive_user_groups_when_active_flag_sent(self, user_util, xhr_header): self.log_user() user_group = user_util.create_user_group(active=False) user_group_name = user_group.users_group_name response = self.app.get( - route_path('user_group_autocomplete_data', - params=dict(active='0')), - extra_environ=xhr_header, status=200) + route_path("user_group_autocomplete_data", params=dict(active="0")), extra_environ=xhr_header, status=200 + ) result = json.loads(response.body) - values = [suggestion['value'] for suggestion in result['suggestions']] + values = [suggestion["value"] for suggestion in result["suggestions"]] assert user_group_name in values response = self.app.get( - route_path('user_group_autocomplete_data', - params=dict(active='1')), - extra_environ=xhr_header, status=200) + route_path("user_group_autocomplete_data", params=dict(active="1")), extra_environ=xhr_header, status=200 + ) result = json.loads(response.body) - values = [suggestion['value'] for suggestion in result['suggestions']] + values = [suggestion["value"] for suggestion in result["suggestions"]] assert user_group_name not in values - @pytest.mark.parametrize('query, count', [ - ('hello1', 0), - ('dev', 1), - ]) + @pytest.mark.parametrize( + "query, count", + [ + ("hello1", 0), + ("dev", 1), + ], + ) def test_result_is_limited_when_query_is_sent(self, user_util, xhr_header, query, count): self.log_user() - user_util._test_name = 'dev-test' + user_util._test_name = "dev-test" user_util.create_user_group() response = self.app.get( - route_path('user_group_autocomplete_data', - params=dict(user_groups='true', - query=query)), - extra_environ=xhr_header, status=200) + route_path("user_group_autocomplete_data", params=dict(user_groups="true", query=query)), + extra_environ=xhr_header, + status=200, + ) result = json.loads(response.body) - assert len(result['suggestions']) == count + assert len(result["suggestions"]) == count diff --git a/rhodecode/apps/home/tests/test_home.py b/rhodecode/apps/home/tests/test_home.py index 84e6945f..f049b42e 100644 --- a/rhodecode/apps/home/tests/test_home.py +++ b/rhodecode/apps/home/tests/test_home.py @@ -32,82 +32,90 @@ fixture = Fixture() class TestHomeController(TestController): - def test_index(self): self.log_user() - response = self.app.get(route_path('home')) + response = self.app.get(route_path("home")) # if global permission is set - response.mustcontain('New Repository') + response.mustcontain("New Repository") def test_index_grid_repos(self, xhr_header): self.log_user() - response = self.app.get(route_path('main_page_repos_data'), extra_environ=xhr_header) + response = self.app.get(route_path("main_page_repos_data"), extra_environ=xhr_header) # search for objects inside the JavaScript JSON for obj in Repository.getAll(): response.mustcontain(''.format(obj.repo_name)) def test_index_grid_repo_groups(self, xhr_header): self.log_user() - response = self.app.get(route_path('main_page_repo_groups_data'), - extra_environ=xhr_header,) + response = self.app.get( + route_path("main_page_repo_groups_data"), + extra_environ=xhr_header, + ) # search for objects inside the JavaScript JSON for obj in RepoGroup.getAll(): response.mustcontain(''.format(obj.group_name)) def test_index_grid_repo_groups_without_access(self, xhr_header, user_util): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") group_ok = user_util.create_repo_group(owner=user) group_id_ok = group_ok.group_id group_forbidden = user_util.create_repo_group(owner=User.get_first_super_admin()) group_id_forbidden = group_forbidden.group_id - user_util.grant_user_permission_to_repo_group(group_forbidden, user, 'group.none') - self.log_user(user.username, 'qweqwe') + user_util.grant_user_permission_to_repo_group(group_forbidden, user, "group.none") + self.log_user(user.username, "qweqwe") - self.app.get(route_path('main_page_repo_groups_data'), - extra_environ=xhr_header, - params={'repo_group_id': group_id_ok}, status=200) + self.app.get( + route_path("main_page_repo_groups_data"), + extra_environ=xhr_header, + params={"repo_group_id": group_id_ok}, + status=200, + ) - self.app.get(route_path('main_page_repo_groups_data'), - extra_environ=xhr_header, - params={'repo_group_id': group_id_forbidden}, status=404) + self.app.get( + route_path("main_page_repo_groups_data"), + extra_environ=xhr_header, + params={"repo_group_id": group_id_forbidden}, + status=404, + ) def test_index_contains_statics_with_ver(self): from rhodecode.lib.base import calculate_version_hash self.log_user() - response = self.app.get(route_path('home')) + response = self.app.get(route_path("home")) - rhodecode_version_hash = calculate_version_hash( - {'beaker.session.secret': 'test-rc-uytcxaz'}) - response.mustcontain('style.css?ver={0}'.format(rhodecode_version_hash)) - response.mustcontain('scripts.min.js?ver={0}'.format(rhodecode_version_hash)) + rhodecode_version_hash = calculate_version_hash({"beaker.session.secret": "test-rc-uytcxaz"}) + response.mustcontain("style.css?ver={0}".format(rhodecode_version_hash)) + response.mustcontain("scripts.min.js?ver={0}".format(rhodecode_version_hash)) def test_index_contains_backend_specific_details(self, backend, xhr_header): self.log_user() - response = self.app.get(route_path('main_page_repos_data'), extra_environ=xhr_header) + response = self.app.get(route_path("main_page_repos_data"), extra_environ=xhr_header) tip = backend.repo.get_commit().raw_id # html in javascript variable: - response.mustcontain(r'', - 'type': 'search', - 'subtype': 'repo', - 'url': h.route_path('search_repo', - repo_name=repo_name, - _query=query_modifier()) - } + "id": -10, + "value": query, + "value_display": label, + "value_icon": '', + "type": "search", + "subtype": "repo", + "url": h.route_path("search_repo", repo_name=repo_name, _query=query_modifier()), + } # commits def query_modifier(): qry = query - return {'q': qry, 'type': 'commit'} + return {"q": qry, "type": "commit"} - label = f'Commit search for `{h.escape(query)}`' + label = f"Commit search for `{h.escape(query)}`" commit_qry = { - 'id': -20, - 'value': query, - 'value_display': label, - 'value_icon': '', - 'type': 'search', - 'subtype': 'repo', - 'url': h.route_path('search_repo', - repo_name=repo_name, - _query=query_modifier()) - } + "id": -20, + "value": query, + "value_display": label, + "value_icon": '', + "type": "search", + "subtype": "repo", + "url": h.route_path("search_repo", repo_name=repo_name, _query=query_modifier()), + } - if repo_context in ['commit', 'commits']: + if repo_context in ["commit", "commits"]: queries.extend([commit_qry, file_qry]) - elif repo_context in ['files', 'summary']: + elif repo_context in ["files", "summary"]: queries.extend([file_qry, commit_qry]) else: queries.extend([commit_qry, file_qry]) @@ -535,42 +539,38 @@ class HomeView(BaseAppView, DataGridAppView): # files def query_modifier(): qry = query - return {'q': qry, 'type': 'content'} + return {"q": qry, "type": "content"} - label = f'File content search for `{query}`' + label = f"File content search for `{query}`" file_qry = { - 'id': -30, - 'value': query, - 'value_display': label, - 'value_icon': '', - 'type': 'search', - 'subtype': 'repo_group', - 'url': h.route_path('search_repo_group', - repo_group_name=repo_group_name, - _query=query_modifier()) - } + "id": -30, + "value": query, + "value_display": label, + "value_icon": '', + "type": "search", + "subtype": "repo_group", + "url": h.route_path("search_repo_group", repo_group_name=repo_group_name, _query=query_modifier()), + } # commits def query_modifier(): qry = query - return {'q': qry, 'type': 'commit'} + return {"q": qry, "type": "commit"} - label = f'Commit search for `{query}`' + label = f"Commit search for `{query}`" commit_qry = { - 'id': -40, - 'value': query, - 'value_display': label, - 'value_icon': '', - 'type': 'search', - 'subtype': 'repo_group', - 'url': h.route_path('search_repo_group', - repo_group_name=repo_group_name, - _query=query_modifier()) - } + "id": -40, + "value": query, + "value_display": label, + "value_icon": '', + "type": "search", + "subtype": "repo_group", + "url": h.route_path("search_repo_group", repo_group_name=repo_group_name, _query=query_modifier()), + } - if repo_context in ['commit', 'commits']: + if repo_context in ["commit", "commits"]: queries.extend([commit_qry, file_qry]) - elif repo_context in ['files', 'summary']: + elif repo_context in ["files", "summary"]: queries.extend([file_qry, commit_qry]) else: queries.extend([commit_qry, file_qry]) @@ -579,26 +579,26 @@ class HomeView(BaseAppView, DataGridAppView): if not queries: queries.append( { - 'id': -1, - 'value': query, - 'value_display': f'File content search for: `{query}`', - 'value_icon': '', - 'type': 'search', - 'subtype': 'global', - 'url': h.route_path('search', - _query={'q': query, 'type': 'content'}) - }) + "id": -1, + "value": query, + "value_display": f"File content search for: `{query}`", + "value_icon": '', + "type": "search", + "subtype": "global", + "url": h.route_path("search", _query={"q": query, "type": "content"}), + } + ) queries.append( { - 'id': -2, - 'value': query, - 'value_display': f'Commit search for: `{query}`', - 'value_icon': '', - 'type': 'search', - 'subtype': 'global', - 'url': h.route_path('search', - _query={'q': query, 'type': 'commit'}) - }) + "id": -2, + "value": query, + "value_display": f"Commit search for: `{query}`", + "value_icon": '', + "type": "search", + "subtype": "global", + "url": h.route_path("search", _query={"q": query, "type": "commit"}), + } + ) return queries @@ -608,33 +608,28 @@ class HomeView(BaseAppView, DataGridAppView): _ = self.request.translate - query = self.request.GET.get('query') - log.debug('generating main filter data, query %s', query) + query = self.request.GET.get("query") + log.debug("generating main filter data, query %s", query) res = [] if not query: - return {'suggestions': res} + return {"suggestions": res} def no_match(name): - return { - 'id': -1, - 'value': "", - 'value_display': name, - 'type': 'text', - 'url': "" - } + return {"id": -1, "value": "", "value_display": name, "type": "text", "url": ""} + searcher = searcher_from_config(self.request.registry.settings) has_specialized_search = False # set repo context repo = None - repo_id = safe_int(self.request.GET.get('search_context[repo_id]')) + repo_id = safe_int(self.request.GET.get("search_context[repo_id]")) if repo_id: repo = Repository.get(repo_id) # set group context repo_group = None - repo_group_id = safe_int(self.request.GET.get('search_context[repo_group_id]')) + repo_group_id = safe_int(self.request.GET.get("search_context[repo_group_id]")) if repo_group_id: repo_group = RepoGroup.get(repo_group_id) prefix_match = False @@ -648,7 +643,7 @@ class HomeView(BaseAppView, DataGridAppView): res.append(serialized_user) elif prefix_match: has_specialized_search = True - res.append(no_match('No matching users found')) + res.append(no_match("No matching users found")) # user_group: type search if not prefix_match: @@ -659,7 +654,7 @@ class HomeView(BaseAppView, DataGridAppView): res.append(serialized_user_group) elif prefix_match: has_specialized_search = True - res.append(no_match('No matching user groups found')) + res.append(no_match("No matching user groups found")) # pr: type search if not prefix_match: @@ -670,17 +665,16 @@ class HomeView(BaseAppView, DataGridAppView): res.append(serialized_pull_request) elif prefix_match: has_specialized_search = True - res.append(no_match('No matching pull requests found')) + res.append(no_match("No matching pull requests found")) # FTS commit: type search if not prefix_match: - commits, prefix_match = self._get_hash_commit_list( - c.auth_user, searcher, query, repo, repo_group) + commits, prefix_match = self._get_hash_commit_list(c.auth_user, searcher, query, repo, repo_group) if commits: has_specialized_search = True unique_repos = collections.OrderedDict() for commit in commits: - repo_name = commit['repo'] + repo_name = commit["repo"] unique_repos.setdefault(repo_name, []).append(commit) for _repo, commits in unique_repos.items(): @@ -688,17 +682,16 @@ class HomeView(BaseAppView, DataGridAppView): res.append(commit) elif prefix_match: has_specialized_search = True - res.append(no_match('No matching commits found')) + res.append(no_match("No matching commits found")) # FTS file: type search if not prefix_match: - paths, prefix_match = self._get_path_list( - c.auth_user, searcher, query, repo, repo_group) + paths, prefix_match = self._get_path_list(c.auth_user, searcher, query, repo, repo_group) if paths: has_specialized_search = True unique_repos = collections.OrderedDict() for path in paths: - repo_name = path['repo'] + repo_name = path["repo"] unique_repos.setdefault(repo_name, []).append(path) for repo, paths in unique_repos.items(): @@ -706,11 +699,11 @@ class HomeView(BaseAppView, DataGridAppView): res.append(path) elif prefix_match: has_specialized_search = True - res.append(no_match('No matching files found')) + res.append(no_match("No matching files found")) # main suggestions if not has_specialized_search: - repo_group_name = '' + repo_group_name = "" if repo_group: repo_group_name = repo_group.group_name @@ -726,9 +719,9 @@ class HomeView(BaseAppView, DataGridAppView): res.append(serialized_repo) if not repos and not repo_groups: - res.append(no_match('No matches found')) + res.append(no_match("No matches found")) - return {'suggestions': res} + return {"suggestions": res} @LoginRequired() def main_page(self): @@ -738,44 +731,39 @@ class HomeView(BaseAppView, DataGridAppView): def _main_page_repo_groups_data(self, repo_group_id): column_map = { - 'name': 'group_name_hash', - 'desc': 'group_description', - 'last_change': 'updated_on', - 'owner': 'user_username', + "name": "group_name_hash", + "desc": "group_description", + "last_change": "updated_on", + "owner": "user_username", } draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) return RepoGroupModel().get_repo_groups_data_table( - draw, start, limit, - search_q, order_by, order_dir, - self._rhodecode_user, repo_group_id) + draw, start, limit, search_q, order_by, order_dir, self._rhodecode_user, repo_group_id + ) def _main_page_repos_data(self, repo_group_id): column_map = { - 'name': 'repo_name', - 'desc': 'description', - 'last_change': 'updated_on', - 'owner': 'user_username', + "name": "repo_name", + "desc": "description", + "last_change": "updated_on", + "owner": "user_username", } draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) return RepoModel().get_repos_data_table( - draw, start, limit, - search_q, order_by, order_dir, - self._rhodecode_user, repo_group_id) + draw, start, limit, search_q, order_by, order_dir, self._rhodecode_user, repo_group_id + ) @LoginRequired() def main_page_repo_groups_data(self): self.load_default_context() - repo_group_id = safe_int(self.request.GET.get('repo_group_id')) + repo_group_id = safe_int(self.request.GET.get("repo_group_id")) if repo_group_id: group = RepoGroup.get_or_404(repo_group_id) _perms = AuthUser.repo_group_read_perms - if not HasRepoGroupPermissionAny(*_perms)( - group.group_name, 'user is allowed to list repo group children'): + if not HasRepoGroupPermissionAny(*_perms)(group.group_name, "user is allowed to list repo group children"): raise HTTPNotFound() return self._main_page_repo_groups_data(repo_group_id) @@ -783,13 +771,12 @@ class HomeView(BaseAppView, DataGridAppView): @LoginRequired() def main_page_repos_data(self): self.load_default_context() - repo_group_id = safe_int(self.request.GET.get('repo_group_id')) + repo_group_id = safe_int(self.request.GET.get("repo_group_id")) if repo_group_id: group = RepoGroup.get_or_404(repo_group_id) _perms = AuthUser.repo_group_read_perms - if not HasRepoGroupPermissionAny(*_perms)( - group.group_name, 'user is allowed to list repo group children'): + if not HasRepoGroupPermissionAny(*_perms)(group.group_name, "user is allowed to list repo group children"): raise HTTPNotFound() return self._main_page_repos_data(repo_group_id) @@ -810,11 +797,11 @@ class HomeView(BaseAppView, DataGridAppView): # Post is required because the payload could be bigger than the maximum # allowed by GET. - text = self.request.POST.get('text') - renderer = self.request.POST.get('renderer') or 'rst' + text = self.request.POST.get("text") + renderer = self.request.POST.get("renderer") or "rst" if text: return h.render(text, renderer=renderer, mentions=True) - return '' + return "" @LoginRequired() @CSRFRequired() @@ -825,8 +812,8 @@ class HomeView(BaseAppView, DataGridAppView): # Post is required because the payload could be bigger than the maximum # allowed by GET. - text = self.request.POST.get('text') - file_path = self.request.POST.get('file_path') + text = self.request.POST.get("text") + file_path = self.request.POST.get("file_path") renderer = h.renderer_from_filename(file_path) @@ -834,21 +821,20 @@ class HomeView(BaseAppView, DataGridAppView): return h.render(text, renderer=renderer, mentions=True) else: self.load_default_context() - _render = self.request.get_partial_renderer( - 'rhodecode:templates/files/file_content.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/files/file_content.mako") lines = filenode_as_lines_tokens(FileNode(file_path, text)) - return _render('render_lines', lines) + return _render("render_lines", lines) @LoginRequired() @CSRFRequired() def store_user_session_attr(self): - key = self.request.POST.get('key') - val = self.request.POST.get('val') + key = self.request.POST.get("key") + val = self.request.POST.get("val") existing_value = self.request.session.get(key) if existing_value != val: self.request.session[key] = val - return f'stored:{key}:{val}' + return f"stored:{key}:{val}" diff --git a/rhodecode/apps/hovercards/__init__.py b/rhodecode/apps/hovercards/__init__.py index 04f6c236..b63a2727 100644 --- a/rhodecode/apps/hovercards/__init__.py +++ b/rhodecode/apps/hovercards/__init__.py @@ -19,47 +19,55 @@ def includeme(config): from rhodecode.apps.hovercards.views import HoverCardsView, HoverCardsRepoView - config.add_route( - name='hovercard_user', - pattern='/_hovercard/user/{user_id}') + + config.add_route(name="hovercard_user", pattern="/_hovercard/user/{user_id}") config.add_view( HoverCardsView, - attr='hovercard_user', - route_name='hovercard_user', request_method='GET', xhr=True, - renderer='rhodecode:templates/hovercards/hovercard_user.mako') + attr="hovercard_user", + route_name="hovercard_user", + request_method="GET", + xhr=True, + renderer="rhodecode:templates/hovercards/hovercard_user.mako", + ) - config.add_route( - name='hovercard_username', - pattern='/_hovercard/username/{username}') + config.add_route(name="hovercard_username", pattern="/_hovercard/username/{username}") config.add_view( HoverCardsView, - attr='hovercard_username', - route_name='hovercard_username', request_method='GET', xhr=True, - renderer='rhodecode:templates/hovercards/hovercard_user.mako') + attr="hovercard_username", + route_name="hovercard_username", + request_method="GET", + xhr=True, + renderer="rhodecode:templates/hovercards/hovercard_user.mako", + ) - config.add_route( - name='hovercard_user_group', - pattern='/_hovercard/user_group/{user_group_id}') + config.add_route(name="hovercard_user_group", pattern="/_hovercard/user_group/{user_group_id}") config.add_view( HoverCardsView, - attr='hovercard_user_group', - route_name='hovercard_user_group', request_method='GET', xhr=True, - renderer='rhodecode:templates/hovercards/hovercard_user_group.mako') + attr="hovercard_user_group", + route_name="hovercard_user_group", + request_method="GET", + xhr=True, + renderer="rhodecode:templates/hovercards/hovercard_user_group.mako", + ) - config.add_route( - name='hovercard_pull_request', - pattern='/_hovercard/pull_request/{pull_request_id}') + config.add_route(name="hovercard_pull_request", pattern="/_hovercard/pull_request/{pull_request_id}") config.add_view( HoverCardsView, - attr='hovercard_pull_request', - route_name='hovercard_pull_request', request_method='GET', xhr=True, - renderer='rhodecode:templates/hovercards/hovercard_pull_request.mako') + attr="hovercard_pull_request", + route_name="hovercard_pull_request", + request_method="GET", + xhr=True, + renderer="rhodecode:templates/hovercards/hovercard_pull_request.mako", + ) config.add_route( - name='hovercard_repo_commit', - pattern='/_hovercard/commit/{repo_name:.*?[^/]}/{commit_id}', repo_route=True) + name="hovercard_repo_commit", pattern="/_hovercard/commit/{repo_name:.*?[^/]}/{commit_id}", repo_route=True + ) config.add_view( HoverCardsRepoView, - attr='hovercard_repo_commit', - route_name='hovercard_repo_commit', request_method='GET', xhr=True, - renderer='rhodecode:templates/hovercards/hovercard_repo_commit.mako') + attr="hovercard_repo_commit", + route_name="hovercard_repo_commit", + request_method="GET", + xhr=True, + renderer="rhodecode:templates/hovercards/hovercard_repo_commit.mako", + ) diff --git a/rhodecode/apps/hovercards/views.py b/rhodecode/apps/hovercards/views.py index 5ce629f9..f433beab 100644 --- a/rhodecode/apps/hovercards/views.py +++ b/rhodecode/apps/hovercards/views.py @@ -26,8 +26,12 @@ from pyramid.httpexceptions import HTTPNotFound from rhodecode.apps._base import BaseAppView, RepoAppView from rhodecode.lib import helpers as h from rhodecode.lib.auth import ( - LoginRequired, NotAnonymous, HasRepoGroupPermissionAnyDecorator, CSRFRequired, - HasRepoPermissionAnyDecorator) + LoginRequired, + NotAnonymous, + HasRepoGroupPermissionAnyDecorator, + CSRFRequired, + HasRepoPermissionAnyDecorator, +) from rhodecode.lib.codeblocks import filenode_as_lines_tokens from rhodecode.lib.index import searcher_from_config from rhodecode.lib.utils2 import str2bool, safe_int @@ -35,7 +39,17 @@ from rhodecode.lib.ext_json import json from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError, EmptyRepositoryError from rhodecode.lib.vcs.nodes import FileNode from rhodecode.model.db import ( - func, true, or_, case, in_filter_generator, Repository, RepoGroup, User, UserGroup, PullRequest) + func, + true, + or_, + case, + in_filter_generator, + Repository, + RepoGroup, + User, + UserGroup, + PullRequest, +) from rhodecode.model.repo import RepoModel from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.scm import RepoGroupList, RepoList @@ -46,7 +60,6 @@ log = logging.getLogger(__name__) class HoverCardsView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @@ -54,14 +67,14 @@ class HoverCardsView(BaseAppView): @LoginRequired() def hovercard_user(self): c = self.load_default_context() - user_id = self.request.matchdict['user_id'] + user_id = self.request.matchdict["user_id"] c.user = User.get_or_404(user_id) return self._get_template_context(c) @LoginRequired() def hovercard_username(self): c = self.load_default_context() - username = self.request.matchdict['username'] + username = self.request.matchdict["username"] c.user = User.get_by_username(username) if not c.user: raise HTTPNotFound() @@ -71,18 +84,16 @@ class HoverCardsView(BaseAppView): @LoginRequired() def hovercard_user_group(self): c = self.load_default_context() - user_group_id = self.request.matchdict['user_group_id'] + user_group_id = self.request.matchdict["user_group_id"] c.user_group = UserGroup.get_or_404(user_group_id) return self._get_template_context(c) @LoginRequired() def hovercard_pull_request(self): c = self.load_default_context() - c.pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) - perms = ['repository.read', 'repository.write', 'repository.admin'] - c.can_view_pr = h.HasRepoPermissionAny(*perms)( - c.pull_request.target_repo.repo_name) + c.pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) + perms = ["repository.read", "repository.write", "repository.admin"] + c.can_view_pr = h.HasRepoPermissionAny(*perms)(c.pull_request.target_repo.repo_name) return self._get_template_context(c) @@ -92,14 +103,13 @@ class HoverCardsRepoView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def hovercard_repo_commit(self): c = self.load_default_context() - commit_id = self.request.matchdict['commit_id'] - pre_load = ['author', 'branch', 'date', 'message'] + commit_id = self.request.matchdict["commit_id"] + pre_load = ["author", "branch", "date", "message"] try: - c.commit = self.rhodecode_vcs_repo.get_commit( - commit_id=commit_id, pre_load=pre_load) + c.commit = self.rhodecode_vcs_repo.get_commit(commit_id=commit_id, pre_load=pre_load) except (CommitDoesNotExistError, EmptyRepositoryError): raise HTTPNotFound() diff --git a/rhodecode/apps/journal/__init__.py b/rhodecode/apps/journal/__init__.py index 75f6388a..9df10ef5 100644 --- a/rhodecode/apps/journal/__init__.py +++ b/rhodecode/apps/journal/__init__.py @@ -23,77 +23,48 @@ from rhodecode.apps._base import ADMIN_PREFIX def admin_routes(config): from rhodecode.apps.journal.views import JournalView - config.add_route( - name='journal', pattern='/journal') - config.add_view( - JournalView, - attr='journal', - route_name='journal', request_method='GET', - renderer=None) + config.add_route(name="journal", pattern="/journal") + config.add_view(JournalView, attr="journal", route_name="journal", request_method="GET", renderer=None) - config.add_route( - name='journal_rss', pattern='/journal/rss') - config.add_view( - JournalView, - attr='journal_rss', - route_name='journal_rss', request_method='GET', - renderer=None) + config.add_route(name="journal_rss", pattern="/journal/rss") + config.add_view(JournalView, attr="journal_rss", route_name="journal_rss", request_method="GET", renderer=None) - config.add_route( - name='journal_atom', pattern='/journal/atom') - config.add_view( - JournalView, - attr='journal_atom', - route_name='journal_atom', request_method='GET', - renderer=None) + config.add_route(name="journal_atom", pattern="/journal/atom") + config.add_view(JournalView, attr="journal_atom", route_name="journal_atom", request_method="GET", renderer=None) - config.add_route( - name='journal_public', pattern='/public_journal') + config.add_route(name="journal_public", pattern="/public_journal") config.add_view( - JournalView, - attr='journal_public', - route_name='journal_public', request_method='GET', - renderer=None) + JournalView, attr="journal_public", route_name="journal_public", request_method="GET", renderer=None + ) - config.add_route( - name='journal_public_atom', pattern='/public_journal/atom') + config.add_route(name="journal_public_atom", pattern="/public_journal/atom") config.add_view( - JournalView, - attr='journal_public_atom', - route_name='journal_public_atom', request_method='GET', - renderer=None) + JournalView, attr="journal_public_atom", route_name="journal_public_atom", request_method="GET", renderer=None + ) - config.add_route( - name='journal_public_atom_old', pattern='/public_journal_atom') + config.add_route(name="journal_public_atom_old", pattern="/public_journal_atom") config.add_view( JournalView, - attr='journal_public_atom', - route_name='journal_public_atom_old', request_method='GET', - renderer=None) + attr="journal_public_atom", + route_name="journal_public_atom_old", + request_method="GET", + renderer=None, + ) - config.add_route( - name='journal_public_rss', pattern='/public_journal/rss') + config.add_route(name="journal_public_rss", pattern="/public_journal/rss") config.add_view( - JournalView, - attr='journal_public_rss', - route_name='journal_public_rss', request_method='GET', - renderer=None) + JournalView, attr="journal_public_rss", route_name="journal_public_rss", request_method="GET", renderer=None + ) - config.add_route( - name='journal_public_rss_old', pattern='/public_journal_rss') + config.add_route(name="journal_public_rss_old", pattern="/public_journal_rss") config.add_view( - JournalView, - attr='journal_public_rss', - route_name='journal_public_rss_old', request_method='GET', - renderer=None) + JournalView, attr="journal_public_rss", route_name="journal_public_rss_old", request_method="GET", renderer=None + ) - config.add_route( - name='toggle_following', pattern='/toggle_following') + config.add_route(name="toggle_following", pattern="/toggle_following") config.add_view( - JournalView, - attr='toggle_following', - route_name='toggle_following', request_method='POST', - renderer='json_ext') + JournalView, attr="toggle_following", route_name="toggle_following", request_method="POST", renderer="json_ext" + ) def includeme(config): diff --git a/rhodecode/apps/journal/tests/test_journal.py b/rhodecode/apps/journal/tests/test_journal.py index 54454587..7d3aab23 100644 --- a/rhodecode/apps/journal/tests/test_journal.py +++ b/rhodecode/apps/journal/tests/test_journal.py @@ -28,23 +28,18 @@ from rhodecode.tests.routes import route_path class TestJournalViews(TestController): - def test_journal(self): self.log_user() - response = self.app.get(route_path('journal')) + response = self.app.get(route_path("journal")) # response.mustcontain( # """
%s
""" % datetime.date.today()) - @pytest.mark.parametrize("feed_type, content_type", [ - ('rss', "application/rss+xml"), - ('atom', "application/atom+xml") - ]) + @pytest.mark.parametrize( + "feed_type, content_type", [("rss", "application/rss+xml"), ("atom", "application/atom+xml")] + ) def test_journal_feed(self, feed_type, content_type): self.log_user() - response = self.app.get( - route_path( - 'journal_{}'.format(feed_type)), - status=200) + response = self.app.get(route_path("journal_{}".format(feed_type)), status=200) assert response.content_type == content_type @@ -52,35 +47,33 @@ class TestJournalViews(TestController): user = self.log_user() repo = Repository.get_by_repo_name(backend.repo_name) repo_id = repo.repo_id - self.app.post( - route_path('toggle_following'), {'follows_repo_id': repo_id, - 'csrf_token': self.csrf_token}) + self.app.post(route_path("toggle_following"), {"follows_repo_id": repo_id, "csrf_token": self.csrf_token}) - followings = UserFollowing.query()\ - .filter(UserFollowing.user_id == user['user_id'])\ - .filter(UserFollowing.follows_repo_id == repo_id).all() + followings = ( + UserFollowing.query() + .filter(UserFollowing.user_id == user["user_id"]) + .filter(UserFollowing.follows_repo_id == repo_id) + .all() + ) assert len(followings) == 0 - self.app.post( - route_path('toggle_following'), {'follows_repo_id': repo_id, - 'csrf_token': self.csrf_token}) + self.app.post(route_path("toggle_following"), {"follows_repo_id": repo_id, "csrf_token": self.csrf_token}) - followings = UserFollowing.query()\ - .filter(UserFollowing.user_id == user['user_id'])\ - .filter(UserFollowing.follows_repo_id == repo_id).all() + followings = ( + UserFollowing.query() + .filter(UserFollowing.user_id == user["user_id"]) + .filter(UserFollowing.follows_repo_id == repo_id) + .all() + ) assert len(followings) == 1 - @pytest.mark.parametrize("feed_type, content_type", [ - ('rss', "application/rss+xml"), - ('atom', "application/atom+xml") - ]) + @pytest.mark.parametrize( + "feed_type, content_type", [("rss", "application/rss+xml"), ("atom", "application/atom+xml")] + ) def test_public_journal_feed(self, feed_type, content_type): self.log_user() - response = self.app.get( - route_path( - 'journal_public_{}'.format(feed_type)), - status=200) + response = self.app.get(route_path("journal_public_{}".format(feed_type)), status=200) assert response.content_type == content_type diff --git a/rhodecode/apps/journal/views.py b/rhodecode/apps/journal/views.py index 2638428d..6deb0441 100644 --- a/rhodecode/apps/journal/views.py +++ b/rhodecode/apps/journal/views.py @@ -24,8 +24,7 @@ from pyramid.response import Response from pyramid.renderers import render from rhodecode.apps._base import BaseAppView -from rhodecode.model.db import ( - or_, joinedload, Repository, UserLog, UserFollowing, User, UserApiKeys) +from rhodecode.model.db import or_, joinedload, Repository, UserLog, UserFollowing, User, UserApiKeys from rhodecode.model.meta import Session import rhodecode.lib.helpers as h from rhodecode.lib.helpers import SqlPage @@ -39,26 +38,25 @@ log = logging.getLogger(__name__) class JournalView(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context(include_app_defaults=True) self._load_defaults(c.rhodecode_name) # TODO(marcink): what is this, why we need a global register ? - c.search_term = self.request.GET.get('filter') or '' + c.search_term = self.request.GET.get("filter") or "" return c def _get_config(self, rhodecode_name): import rhodecode + config = rhodecode.CONFIG return { - 'language': 'en-us', - 'feed_ttl': '5', # TTL of feed, - 'feed_items_per_page': - safe_int(config.get('rss_items_per_page', 20)), - 'rhodecode_name': rhodecode_name + "language": "en-us", + "feed_ttl": "5", # TTL of feed, + "feed_items_per_page": safe_int(config.get("rss_items_per_page", 20)), + "rhodecode_name": rhodecode_name, } def _load_defaults(self, rhodecode_name): @@ -66,8 +64,8 @@ class JournalView(BaseAppView): # common values for feeds self.language = config["language"] self.ttl = config["feed_ttl"] - self.feed_items_per_page = config['feed_items_per_page'] - self.rhodecode_name = config['rhodecode_name'] + self.feed_items_per_page = config["feed_items_per_page"] + self.rhodecode_name = config["rhodecode_name"] def _get_daily_aggregate(self, journal): groups = [] @@ -75,81 +73,71 @@ class JournalView(BaseAppView): user_group = [] # groupby username if it's a present value, else # fallback to journal username - for _, g2 in itertools.groupby( - list(g), lambda x: x.user.username if x.user else x.username): + for _, g2 in itertools.groupby(list(g), lambda x: x.user.username if x.user else x.username): l = list(g2) user_group.append((l[0].user, l)) - groups.append((k, user_group,)) + groups.append( + ( + k, + user_group, + ) + ) return groups def _get_journal_data(self, following_repos, search_term): - repo_ids = [x.follows_repository.repo_id for x in following_repos - if x.follows_repository is not None] - user_ids = [x.follows_user.user_id for x in following_repos - if x.follows_user is not None] + repo_ids = [x.follows_repository.repo_id for x in following_repos if x.follows_repository is not None] + user_ids = [x.follows_user.user_id for x in following_repos if x.follows_user is not None] filtering_criterion = None if repo_ids and user_ids: - filtering_criterion = or_(UserLog.repository_id.in_(repo_ids), - UserLog.user_id.in_(user_ids)) + filtering_criterion = or_(UserLog.repository_id.in_(repo_ids), UserLog.user_id.in_(user_ids)) if repo_ids and not user_ids: filtering_criterion = UserLog.repository_id.in_(repo_ids) if not repo_ids and user_ids: filtering_criterion = UserLog.user_id.in_(user_ids) if filtering_criterion is not None: - journal = Session().query(UserLog)\ - .options(joinedload(UserLog.user))\ - .options(joinedload(UserLog.repository)) + journal = Session().query(UserLog).options(joinedload(UserLog.user)).options(joinedload(UserLog.repository)) # filter try: journal = user_log_filter(journal, search_term) except Exception: # we want this to crash for now raise - journal = journal.filter(filtering_criterion)\ - .order_by(UserLog.action_date.desc()) + journal = journal.filter(filtering_criterion).order_by(UserLog.action_date.desc()) else: journal = [] return journal def feed_uid(self, entry_id): - return '{}:{}'.format('journal', md5_safe(str(entry_id))) + return "{}:{}".format("journal", md5_safe(str(entry_id))) def _atom_feed(self, repos, search_term, public=True): _ = self.request.translate journal = self._get_journal_data(repos, search_term) if public: - _link = h.route_url('journal_public_atom') - _desc = '%s %s %s' % (self.rhodecode_name, _('public journal'), - 'atom feed') + _link = h.route_url("journal_public_atom") + _desc = "%s %s %s" % (self.rhodecode_name, _("public journal"), "atom feed") else: - _link = h.route_url('journal_atom') - _desc = '%s %s %s' % (self.rhodecode_name, _('journal'), 'atom feed') + _link = h.route_url("journal_atom") + _desc = "%s %s %s" % (self.rhodecode_name, _("journal"), "atom feed") - feed = Atom1Feed( - title=_desc, link=_link, description=_desc, - language=self.language, ttl=self.ttl) + feed = Atom1Feed(title=_desc, link=_link, description=_desc, language=self.language, ttl=self.ttl) - for entry in journal[:self.feed_items_per_page]: + for entry in journal[: self.feed_items_per_page]: user = entry.user if user is None: # fix deleted users - user = AttributeDict({'short_contact': entry.username, - 'email': '', - 'full_contact': ''}) - action, action_extra, ico = h.action_parser( - self.request, entry, feed=True) - title = "%s - %s %s" % (user.short_contact, action(), - entry.repository.repo_name) + user = AttributeDict({"short_contact": entry.username, "email": "", "full_contact": ""}) + action, action_extra, ico = h.action_parser(self.request, entry, feed=True) + title = "%s - %s %s" % (user.short_contact, action(), entry.repository.repo_name) desc = action_extra() - _url = h.route_url('home') + _url = h.route_url("home") if entry.repository is not None: - _url = h.route_url('repo_commits', - repo_name=entry.repository.repo_name) + _url = h.route_url("repo_commits", repo_name=entry.repository.repo_name) feed.add_item( unique_id=self.feed_uid(entry.user_log_id), @@ -158,9 +146,10 @@ class JournalView(BaseAppView): link=_url, author_email=user.email, author_name=user.full_contact, - description=desc) + description=desc, + ) - response = Response(feed.writeString('utf-8')) + response = Response(feed.writeString("utf-8")) response.content_type = feed.content_type return response @@ -168,34 +157,25 @@ class JournalView(BaseAppView): _ = self.request.translate journal = self._get_journal_data(repos, search_term) if public: - _link = h.route_url('journal_public_atom') - _desc = '%s %s %s' % ( - self.rhodecode_name, _('public journal'), 'rss feed') + _link = h.route_url("journal_public_atom") + _desc = "%s %s %s" % (self.rhodecode_name, _("public journal"), "rss feed") else: - _link = h.route_url('journal_atom') - _desc = '%s %s %s' % ( - self.rhodecode_name, _('journal'), 'rss feed') + _link = h.route_url("journal_atom") + _desc = "%s %s %s" % (self.rhodecode_name, _("journal"), "rss feed") - feed = Rss201rev2Feed( - title=_desc, link=_link, description=_desc, - language=self.language, ttl=self.ttl) + feed = Rss201rev2Feed(title=_desc, link=_link, description=_desc, language=self.language, ttl=self.ttl) - for entry in journal[:self.feed_items_per_page]: + for entry in journal[: self.feed_items_per_page]: user = entry.user if user is None: # fix deleted users - user = AttributeDict({'short_contact': entry.username, - 'email': '', - 'full_contact': ''}) - action, action_extra, ico = h.action_parser( - self.request, entry, feed=True) - title = "%s - %s %s" % (user.short_contact, action(), - entry.repository.repo_name) + user = AttributeDict({"short_contact": entry.username, "email": "", "full_contact": ""}) + action, action_extra, ico = h.action_parser(self.request, entry, feed=True) + title = "%s - %s %s" % (user.short_contact, action(), entry.repository.repo_name) desc = action_extra() - _url = h.route_url('home') + _url = h.route_url("home") if entry.repository is not None: - _url = h.route_url('repo_commits', - repo_name=entry.repository.repo_name) + _url = h.route_url("repo_commits", repo_name=entry.repository.repo_name) feed.add_item( unique_id=self.feed_uid(entry.user_log_id), @@ -204,9 +184,10 @@ class JournalView(BaseAppView): link=_url, author_email=user.email, author_name=user.full_contact, - description=desc) + description=desc, + ) - response = Response(feed.writeString('utf-8')) + response = Response(feed.writeString("utf-8")) response.content_type = feed.content_type return response @@ -215,36 +196,33 @@ class JournalView(BaseAppView): def journal(self): c = self.load_default_context() - p = safe_int(self.request.GET.get('page', 1), 1) + p = safe_int(self.request.GET.get("page", 1), 1) c.user = User.get(self._rhodecode_user.user_id) - following = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ + following = ( + Session() + .query(UserFollowing) + .filter(UserFollowing.user_id == self._rhodecode_user.user_id) + .options(joinedload(UserFollowing.follows_repository)) .all() + ) journal = self._get_journal_data(following, c.search_term) def url_generator(page_num): - query_params = { - 'page': page_num, - 'filter': c.search_term - } + query_params = {"page": page_num, "filter": c.search_term} return self.request.current_route_path(_query=query_params) - c.journal_pager = SqlPage( - journal, page=p, items_per_page=20, url_maker=url_generator) + c.journal_pager = SqlPage(journal, page=p, items_per_page=20, url_maker=url_generator) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render( - 'rhodecode:templates/journal/journal_data.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/journal/journal_data.mako", self._get_template_context(c), self.request + ) if self.request.is_xhr: return Response(c.journal_data) - html = render( - 'rhodecode:templates/journal/journal.mako', - self._get_template_context(c), self.request) + html = render("rhodecode:templates/journal/journal.mako", self._get_template_context(c), self.request) return Response(html) @LoginRequired(auth_token_access=[UserApiKeys.ROLE_FEED]) @@ -254,10 +232,13 @@ class JournalView(BaseAppView): Produce an atom-1.0 feed via feedgenerator module """ c = self.load_default_context() - following_repos = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ + following_repos = ( + Session() + .query(UserFollowing) + .filter(UserFollowing.user_id == self._rhodecode_user.user_id) + .options(joinedload(UserFollowing.follows_repository)) .all() + ) return self._atom_feed(following_repos, c.search_term, public=False) @LoginRequired(auth_token_access=[UserApiKeys.ROLE_FEED]) @@ -267,45 +248,46 @@ class JournalView(BaseAppView): Produce an rss feed via feedgenerator module """ c = self.load_default_context() - following_repos = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ + following_repos = ( + Session() + .query(UserFollowing) + .filter(UserFollowing.user_id == self._rhodecode_user.user_id) + .options(joinedload(UserFollowing.follows_repository)) .all() + ) return self._rss_feed(following_repos, c.search_term, public=False) @LoginRequired() def journal_public(self): c = self.load_default_context() # Return a rendered template - p = safe_int(self.request.GET.get('page', 1), 1) + p = safe_int(self.request.GET.get("page", 1), 1) - c.following = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ + c.following = ( + Session() + .query(UserFollowing) + .filter(UserFollowing.user_id == self._rhodecode_user.user_id) + .options(joinedload(UserFollowing.follows_repository)) .all() + ) journal = self._get_journal_data(c.following, c.search_term) def url_generator(page_num): - query_params = { - 'page': page_num - } + query_params = {"page": page_num} return self.request.current_route_path(_query=query_params) - c.journal_pager = SqlPage( - journal, page=p, items_per_page=20, url_maker=url_generator) + c.journal_pager = SqlPage(journal, page=p, items_per_page=20, url_maker=url_generator) c.journal_day_aggreagate = self._get_daily_aggregate(c.journal_pager) c.journal_data = render( - 'rhodecode:templates/journal/journal_data.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/journal/journal_data.mako", self._get_template_context(c), self.request + ) if self.request.is_xhr: return Response(c.journal_data) - html = render( - 'rhodecode:templates/journal/public_journal.mako', - self._get_template_context(c), self.request) + html = render("rhodecode:templates/journal/public_journal.mako", self._get_template_context(c), self.request) return Response(html) @LoginRequired(auth_token_access=[UserApiKeys.ROLE_FEED]) @@ -314,10 +296,13 @@ class JournalView(BaseAppView): Produce an atom-1.0 feed via feedgenerator module """ c = self.load_default_context() - following_repos = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ + following_repos = ( + Session() + .query(UserFollowing) + .filter(UserFollowing.user_id == self._rhodecode_user.user_id) + .options(joinedload(UserFollowing.follows_repository)) .all() + ) return self._atom_feed(following_repos, c.search_term) @@ -327,10 +312,13 @@ class JournalView(BaseAppView): Produce an rss2 feed via feedgenerator module """ c = self.load_default_context() - following_repos = Session().query(UserFollowing)\ - .filter(UserFollowing.user_id == self._rhodecode_user.user_id)\ - .options(joinedload(UserFollowing.follows_repository))\ + following_repos = ( + Session() + .query(UserFollowing) + .filter(UserFollowing.user_id == self._rhodecode_user.user_id) + .options(joinedload(UserFollowing.follows_repository)) .all() + ) return self._rss_feed(following_repos, c.search_term) @@ -338,24 +326,24 @@ class JournalView(BaseAppView): @NotAnonymous() @CSRFRequired() def toggle_following(self): - user_id = self.request.POST.get('follows_user_id') + user_id = self.request.POST.get("follows_user_id") if user_id: try: ScmModel().toggle_following_user(user_id, self._rhodecode_user.user_id) Session().commit() - return 'ok' + return "ok" except Exception: raise HTTPBadRequest() - repo_id = self.request.POST.get('follows_repo_id') + repo_id = self.request.POST.get("follows_repo_id") repo = Repository.get_or_404(repo_id) - perm_set = ['repository.read', 'repository.write', 'repository.admin'] - has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, 'RepoWatch check') + perm_set = ["repository.read", "repository.write", "repository.admin"] + has_perm = HasRepoPermissionAny(*perm_set)(repo.repo_name, "RepoWatch check") if repo and has_perm: try: ScmModel().toggle_following_repo(repo_id, self._rhodecode_user.user_id) Session().commit() - return 'ok' + return "ok" except Exception: raise HTTPBadRequest() diff --git a/rhodecode/apps/login/__init__.py b/rhodecode/apps/login/__init__.py index 8447f15a..577774c0 100644 --- a/rhodecode/apps/login/__init__.py +++ b/rhodecode/apps/login/__init__.py @@ -22,80 +22,73 @@ from rhodecode.apps._base import ADMIN_PREFIX def includeme(config): from rhodecode.apps.login.views import LoginView - - config.add_route( - name='login', - pattern=ADMIN_PREFIX + '/login') - config.add_view( - LoginView, - attr='login', - route_name='login', request_method='GET', - renderer='rhodecode:templates/login.mako') - config.add_view( - LoginView, - attr='login_post', - route_name='login', request_method='POST', - renderer='rhodecode:templates/login.mako') - config.add_route( - name='logout', - pattern=ADMIN_PREFIX + '/logout') + config.add_route(name="login", pattern=ADMIN_PREFIX + "/login") + config.add_view( + LoginView, attr="login", route_name="login", request_method="GET", renderer="rhodecode:templates/login.mako" + ) config.add_view( LoginView, - attr='logout', - route_name='logout', request_method='POST') + attr="login_post", + route_name="login", + request_method="POST", + renderer="rhodecode:templates/login.mako", + ) - config.add_route( - name='register', - pattern=ADMIN_PREFIX + '/register') - config.add_view( - LoginView, - attr='register', - route_name='register', request_method='GET', - renderer='rhodecode:templates/register.mako') - config.add_view( - LoginView, - attr='register_post', - route_name='register', request_method='POST', - renderer='rhodecode:templates/register.mako') + config.add_route(name="logout", pattern=ADMIN_PREFIX + "/logout") + config.add_view(LoginView, attr="logout", route_name="logout", request_method="POST") - config.add_route( - name='reset_password', - pattern=ADMIN_PREFIX + '/password_reset') + config.add_route(name="register", pattern=ADMIN_PREFIX + "/register") config.add_view( LoginView, - attr='password_reset', - route_name='reset_password', request_method=('GET', 'POST'), - renderer='rhodecode:templates/password_reset.mako') + attr="register", + route_name="register", + request_method="GET", + renderer="rhodecode:templates/register.mako", + ) + config.add_view( + LoginView, + attr="register_post", + route_name="register", + request_method="POST", + renderer="rhodecode:templates/register.mako", + ) - config.add_route( - name='reset_password_confirmation', - pattern=ADMIN_PREFIX + '/password_reset_confirmation') + config.add_route(name="reset_password", pattern=ADMIN_PREFIX + "/password_reset") config.add_view( LoginView, - attr='password_reset_confirmation', - route_name='reset_password_confirmation', request_method='GET') + attr="password_reset", + route_name="reset_password", + request_method=("GET", "POST"), + renderer="rhodecode:templates/password_reset.mako", + ) - config.add_route( - name='setup_2fa', - pattern=ADMIN_PREFIX + '/setup_2fa') + config.add_route(name="reset_password_confirmation", pattern=ADMIN_PREFIX + "/password_reset_confirmation") config.add_view( - LoginView, - attr='setup_2fa', - route_name='setup_2fa', request_method=['GET', 'POST'], - renderer='rhodecode:templates/configure_2fa.mako') + LoginView, attr="password_reset_confirmation", route_name="reset_password_confirmation", request_method="GET" + ) - config.add_route( - name='check_2fa', - pattern=ADMIN_PREFIX + '/check_2fa') + config.add_route(name="setup_2fa", pattern=ADMIN_PREFIX + "/setup_2fa") config.add_view( LoginView, - attr='verify_2fa', - route_name='check_2fa', request_method='GET', - renderer='rhodecode:templates/verify_2fa.mako') - config.add_view( - LoginView, - attr='verify_2fa', - route_name='check_2fa', request_method='POST', - renderer='rhodecode:templates/verify_2fa.mako') + attr="setup_2fa", + route_name="setup_2fa", + request_method=["GET", "POST"], + renderer="rhodecode:templates/configure_2fa.mako", + ) + config.add_route(name="check_2fa", pattern=ADMIN_PREFIX + "/check_2fa") + config.add_view( + LoginView, + attr="verify_2fa", + route_name="check_2fa", + request_method="GET", + renderer="rhodecode:templates/verify_2fa.mako", + ) + config.add_view( + LoginView, + attr="verify_2fa", + route_name="check_2fa", + request_method="POST", + renderer="rhodecode:templates/verify_2fa.mako", + ) diff --git a/rhodecode/apps/login/tests/test_2fa.py b/rhodecode/apps/login/tests/test_2fa.py index 0e193253..d0856b3d 100644 --- a/rhodecode/apps/login/tests/test_2fa.py +++ b/rhodecode/apps/login/tests/test_2fa.py @@ -10,23 +10,20 @@ from rhodecode.model.settings import SettingsModel fixture = Fixture() -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class Test2FA(object): @classmethod def setup_class(cls): - cls.password = 'valid-one' + cls.password = "valid-one" def test_redirect_to_2fa_setup_if_enabled_for_user(self, user_util): user = user_util.create_user(password=self.password) user.has_enabled_2fa = True - self.app.post( - route_path('login'), - {'username': user.username, - 'password': self.password}) + self.app.post(route_path("login"), {"username": user.username, "password": self.password}) - response = self.app.get('/') + response = self.app.get("/") assert response.status_code == 302 - assert response.location.endswith(route_path('setup_2fa')) + assert response.location.endswith(route_path("setup_2fa")) def test_redirect_to_2fa_check_if_2fa_configured(self, user_util): user = user_util.create_user(password=self.password) @@ -34,13 +31,10 @@ class Test2FA(object): user.init_secret_2fa() Session().add(user) Session().commit() - self.app.post( - route_path('login'), - {'username': user.username, - 'password': self.password}) - response = self.app.get('/') + self.app.post(route_path("login"), {"username": user.username, "password": self.password}) + response = self.app.get("/") assert response.status_code == 302 - assert response.location.endswith(route_path('check_2fa')) + assert response.location.endswith(route_path("check_2fa")) def test_2fa_recovery_codes_works_only_once(self, user_util): user = user_util.create_user(password=self.password) @@ -49,19 +43,16 @@ class Test2FA(object): recovery_code_to_check = user.init_2fa_recovery_codes()[0] Session().add(user) Session().commit() - self.app.post( - route_path('login'), - {'username': user.username, - 'password': self.password}) - response = self.app.post(route_path('check_2fa'), {'totp': recovery_code_to_check}) + self.app.post(route_path("login"), {"username": user.username, "password": self.password}) + response = self.app.post(route_path("check_2fa"), {"totp": recovery_code_to_check}) assert response.status_code == 302 - response = self.app.post(route_path('check_2fa'), {'totp': recovery_code_to_check}) - response.mustcontain('Code is invalid. Try again!') + response = self.app.post(route_path("check_2fa"), {"totp": recovery_code_to_check}) + response.mustcontain("Code is invalid. Try again!") def test_2fa_state_when_forced_by_admin(self, user_util): user = user_util.create_user(password=self.password) user.has_enabled_2fa = False with mock.patch.object( - SettingsModel, 'get_setting_by_name', lambda *a, **kw: AttributeDict(app_settings_value=True)): - + SettingsModel, "get_setting_by_name", lambda *a, **kw: AttributeDict(app_settings_value=True) + ): assert user.has_enabled_2fa diff --git a/rhodecode/apps/login/tests/test_login.py b/rhodecode/apps/login/tests/test_login.py index cf0c5b1b..156b8727 100644 --- a/rhodecode/apps/login/tests/test_login.py +++ b/rhodecode/apps/login/tests/test_login.py @@ -28,18 +28,16 @@ from rhodecode.model.auth_token import AuthTokenModel from rhodecode.model.db import User, Notification, UserApiKeys from rhodecode.model.meta import Session -from rhodecode.tests import ( - assert_session_flash, HG_REPO, TEST_USER_ADMIN_LOGIN, - no_newline_id_generator) +from rhodecode.tests import assert_session_flash, HG_REPO, TEST_USER_ADMIN_LOGIN, no_newline_id_generator from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path fixture = Fixture() -whitelist_view = ['RepoCommitsView:repo_commit_raw'] +whitelist_view = ["RepoCommitsView:repo_commit_raw"] -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestLoginController(object): destroy_users = set() @@ -55,353 +53,333 @@ class TestLoginController(object): assert Notification.query().all() == [] def test_index(self): - response = self.app.get(route_path('login')) - assert response.status == '200 OK' + response = self.app.get(route_path("login")) + assert response.status == "200 OK" # Test response... def test_login_admin_ok(self): - response = self.app.post(route_path('login'), - {'username': 'test_admin', - 'password': 'test12'}, status=302) + response = self.app.post(route_path("login"), {"username": "test_admin", "password": "test12"}, status=302) response = response.follow() session = response.get_session_from_response() - username = session['rhodecode_user'].get('username') - assert username == 'test_admin' - response.mustcontain('logout') + username = session["rhodecode_user"].get("username") + assert username == "test_admin" + response.mustcontain("logout") def test_login_regular_ok(self): - response = self.app.post(route_path('login'), - {'username': 'test_regular', - 'password': 'test12'}, status=302) + response = self.app.post(route_path("login"), {"username": "test_regular", "password": "test12"}, status=302) response = response.follow() session = response.get_session_from_response() - username = session['rhodecode_user'].get('username') - assert username == 'test_regular' - response.mustcontain('logout') + username = session["rhodecode_user"].get("username") + assert username == "test_regular" + response.mustcontain("logout") def test_login_with_primary_email(self): - user_email = 'test_regular@mail.com' - response = self.app.post(route_path('login'), - {'username': user_email, - 'password': 'test12'}, status=302) + user_email = "test_regular@mail.com" + response = self.app.post(route_path("login"), {"username": user_email, "password": "test12"}, status=302) response = response.follow() session = response.get_session_from_response() - user = session['rhodecode_user'] - assert user['username'] == user_email.split('@')[0] - assert user['is_authenticated'] - response.mustcontain('logout') + user = session["rhodecode_user"] + assert user["username"] == user_email.split("@")[0] + assert user["is_authenticated"] + response.mustcontain("logout") def test_login_regular_forbidden_when_super_admin_restriction(self): from rhodecode.authentication.plugins.auth_rhodecode import RhodeCodeAuthPlugin - with fixture.auth_restriction(self.app._pyramid_registry, - RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN): - response = self.app.post(route_path('login'), - {'username': 'test_regular', - 'password': 'test12'}) - response.mustcontain('invalid user name') - response.mustcontain('invalid password') + with fixture.auth_restriction(self.app._pyramid_registry, RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN): + response = self.app.post(route_path("login"), {"username": "test_regular", "password": "test12"}) + + response.mustcontain("invalid user name") + response.mustcontain("invalid password") def test_login_regular_forbidden_when_scope_restriction(self): from rhodecode.authentication.plugins.auth_rhodecode import RhodeCodeAuthPlugin - with fixture.scope_restriction(self.app._pyramid_registry, - RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS): - response = self.app.post(route_path('login'), - {'username': 'test_regular', - 'password': 'test12'}) - response.mustcontain('invalid user name') - response.mustcontain('invalid password') + with fixture.scope_restriction(self.app._pyramid_registry, RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS): + response = self.app.post(route_path("login"), {"username": "test_regular", "password": "test12"}) + + response.mustcontain("invalid user name") + response.mustcontain("invalid password") def test_login_ok_came_from(self): - test_came_from = '/_admin/users?branch=stable' - _url = '{}?came_from={}'.format(route_path('login'), test_came_from) - response = self.app.post( - _url, {'username': 'test_admin', 'password': 'test12'}, status=302) + test_came_from = "/_admin/users?branch=stable" + _url = "{}?came_from={}".format(route_path("login"), test_came_from) + response = self.app.post(_url, {"username": "test_admin", "password": "test12"}, status=302) - assert 'branch=stable' in response.location + assert "branch=stable" in response.location response = response.follow() - assert response.status == '200 OK' - response.mustcontain('Users administration') + assert response.status == "200 OK" + response.mustcontain("Users administration") def test_redirect_to_login_with_get_args(self): with fixture.anon_access(False): - kwargs = {'branch': 'stable'} - response = self.app.get( - h.route_path('repo_summary', repo_name=HG_REPO, _query=kwargs), - status=302) + kwargs = {"branch": "stable"} + response = self.app.get(h.route_path("repo_summary", repo_name=HG_REPO, _query=kwargs), status=302) response_query = urllib.parse.parse_qsl(response.location) - assert 'branch=stable' in response_query[0][1] + assert "branch=stable" in response_query[0][1] def test_login_form_with_get_args(self): - _url = '{}?came_from=/_admin/users,branch=stable'.format(route_path('login')) + _url = "{}?came_from=/_admin/users,branch=stable".format(route_path("login")) response = self.app.get(_url) - assert 'branch%3Dstable' in response.form.action + assert "branch%3Dstable" in response.form.action - @pytest.mark.parametrize("url_came_from", [ - 'data:text/html,', - 'mailto:test@rhodecode.org', - 'file:///etc/passwd', - 'ftp://some.ftp.server', - 'http://other.domain', - ], ids=no_newline_id_generator) + @pytest.mark.parametrize( + "url_came_from", + [ + 'data:text/html,', + "mailto:test@rhodecode.org", + "file:///etc/passwd", + "ftp://some.ftp.server", + "http://other.domain", + ], + ids=no_newline_id_generator, + ) def test_login_bad_came_froms(self, url_came_from): - _url = '{}?came_from={}'.format(route_path('login'), url_came_from) - response = self.app.post( - _url, {'username': 'test_admin', 'password': 'test12'}, status=302) - assert response.status == '302 Found' + _url = "{}?came_from={}".format(route_path("login"), url_came_from) + response = self.app.post(_url, {"username": "test_admin", "password": "test12"}, status=302) + assert response.status == "302 Found" response = response.follow() - assert response.status == '200 OK' - assert response.request.path == '/' + assert response.status == "200 OK" + assert response.request.path == "/" @pytest.mark.xfail(reason="newline params changed behaviour in python3") - @pytest.mark.parametrize("url_came_from", [ - '/\r\nX-Forwarded-Host: \rhttp://example.org', - ], ids=no_newline_id_generator) + @pytest.mark.parametrize( + "url_came_from", + [ + "/\r\nX-Forwarded-Host: \rhttp://example.org", + ], + ids=no_newline_id_generator, + ) def test_login_bad_came_froms_404(self, url_came_from): - _url = '{}?came_from={}'.format(route_path('login'), url_came_from) - response = self.app.post( - _url, {'username': 'test_admin', 'password': 'test12'}, status=302) + _url = "{}?came_from={}".format(route_path("login"), url_came_from) + response = self.app.post(_url, {"username": "test_admin", "password": "test12"}, status=302) response = response.follow() - assert response.status == '404 Not Found' + assert response.status == "404 Not Found" def test_login_short_password(self): - response = self.app.post(route_path('login'), - {'username': 'test_admin', - 'password': 'as'}) - assert response.status == '200 OK' + response = self.app.post(route_path("login"), {"username": "test_admin", "password": "as"}) + assert response.status == "200 OK" - response.mustcontain('Enter 3 characters or more') + response.mustcontain("Enter 3 characters or more") def test_login_wrong_non_ascii_password(self, user_regular): response = self.app.post( - route_path('login'), - {'username': user_regular.username, - 'password': 'invalid-non-asci\xe4'.encode('utf8')}) + route_path("login"), {"username": user_regular.username, "password": "invalid-non-asci\xe4".encode("utf8")} + ) - response.mustcontain('invalid user name') - response.mustcontain('invalid password') + response.mustcontain("invalid user name") + response.mustcontain("invalid password") def test_login_with_non_ascii_password(self, user_util): - password = u'valid-non-ascii\xe4' + password = "valid-non-ascii\xe4" user = user_util.create_user(password=password) - response = self.app.post( - route_path('login'), - {'username': user.username, - 'password': password}) + response = self.app.post(route_path("login"), {"username": user.username, "password": password}) assert response.status_code == 302 def test_login_wrong_username_password(self): - response = self.app.post(route_path('login'), - {'username': 'error', - 'password': 'test12'}) + response = self.app.post(route_path("login"), {"username": "error", "password": "test12"}) - response.mustcontain('invalid user name') - response.mustcontain('invalid password') + response.mustcontain("invalid user name") + response.mustcontain("invalid password") def test_login_admin_ok_password_migration(self, real_crypto_backend): from rhodecode.lib import auth # create new user, with sha256 password - temp_user = 'test_admin_sha256' + temp_user = "test_admin_sha256" user = fixture.create_user(temp_user) - user.password = auth._RhodeCodeCryptoSha256().hash_create( - b'test123') + user.password = auth._RhodeCodeCryptoSha256().hash_create(b"test123") Session().add(user) Session().commit() self.destroy_users.add(temp_user) - response = self.app.post(route_path('login'), - {'username': temp_user, - 'password': 'test123'}, status=302) + response = self.app.post(route_path("login"), {"username": temp_user, "password": "test123"}, status=302) response = response.follow() session = response.get_session_from_response() - username = session['rhodecode_user'].get('username') + username = session["rhodecode_user"].get("username") assert username == temp_user - response.mustcontain('logout') + response.mustcontain("logout") # new password should be bcrypted, after log-in and transfer user = User.get_by_username(temp_user) - assert user.password.startswith('$') + assert user.password.startswith("$") # REGISTRATIONS def test_register(self): - response = self.app.get(route_path('register')) - response.mustcontain('Create an Account') + response = self.app.get(route_path("register")) + response.mustcontain("Create an Account") def test_register_err_same_username(self): - uname = 'test_admin' + uname = "test_admin" response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': uname, - 'password': 'test12', - 'password_confirmation': 'test12', - 'email': 'goodmail@domain.com', - 'firstname': 'test', - 'lastname': 'test' - } + "username": uname, + "password": "test12", + "password_confirmation": "test12", + "email": "goodmail@domain.com", + "firstname": "test", + "lastname": "test", + }, ) assertr = response.assert_response() msg = 'Username "%(username)s" already exists' - msg = msg % {'username': uname} - assertr.element_contains('#username+.error-message', msg) + msg = msg % {"username": uname} + assertr.element_contains("#username+.error-message", msg) def test_register_err_same_email(self): response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': 'test_admin_0', - 'password': 'test12', - 'password_confirmation': 'test12', - 'email': 'test_admin@mail.com', - 'firstname': 'test', - 'lastname': 'test' - } + "username": "test_admin_0", + "password": "test12", + "password_confirmation": "test12", + "email": "test_admin@mail.com", + "firstname": "test", + "lastname": "test", + }, ) assertr = response.assert_response() - msg = 'This e-mail address is already taken' - assertr.element_contains('#email+.error-message', msg) + msg = "This e-mail address is already taken" + assertr.element_contains("#email+.error-message", msg) def test_register_err_same_email_case_sensitive(self): response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': 'test_admin_1', - 'password': 'test12', - 'password_confirmation': 'test12', - 'email': 'TesT_Admin@mail.COM', - 'firstname': 'test', - 'lastname': 'test' - } + "username": "test_admin_1", + "password": "test12", + "password_confirmation": "test12", + "email": "TesT_Admin@mail.COM", + "firstname": "test", + "lastname": "test", + }, ) assertr = response.assert_response() - msg = 'This e-mail address is already taken' - assertr.element_contains('#email+.error-message', msg) + msg = "This e-mail address is already taken" + assertr.element_contains("#email+.error-message", msg) def test_register_err_wrong_data(self): response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': 'xs', - 'password': 'test', - 'password_confirmation': 'test', - 'email': 'goodmailm', - 'firstname': 'test', - 'lastname': 'test' - } + "username": "xs", + "password": "test", + "password_confirmation": "test", + "email": "goodmailm", + "firstname": "test", + "lastname": "test", + }, ) - assert response.status == '200 OK' - response.mustcontain('An email address must contain a single @') - response.mustcontain('Enter a value 6 characters long or more') + assert response.status == "200 OK" + response.mustcontain("An email address must contain a single @") + response.mustcontain("Enter a value 6 characters long or more") def test_register_err_username(self): response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': 'error user', - 'password': 'test12', - 'password_confirmation': 'test12', - 'email': 'goodmailm', - 'firstname': 'test', - 'lastname': 'test' - } + "username": "error user", + "password": "test12", + "password_confirmation": "test12", + "email": "goodmailm", + "firstname": "test", + "lastname": "test", + }, ) - response.mustcontain('An email address must contain a single @') + response.mustcontain("An email address must contain a single @") response.mustcontain( - 'Username may only contain ' - 'alphanumeric characters underscores, ' - 'periods or dashes and must begin with ' - 'alphanumeric character') + "Username may only contain " + "alphanumeric characters underscores, " + "periods or dashes and must begin with " + "alphanumeric character" + ) def test_register_err_case_sensitive(self): - usr = 'Test_Admin' + usr = "Test_Admin" response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': usr, - 'password': 'test12', - 'password_confirmation': 'test12', - 'email': 'goodmailm', - 'firstname': 'test', - 'lastname': 'test' - } + "username": usr, + "password": "test12", + "password_confirmation": "test12", + "email": "goodmailm", + "firstname": "test", + "lastname": "test", + }, ) assertr = response.assert_response() - msg = u'Username "%(username)s" already exists' - msg = msg % {'username': usr} - assertr.element_contains('#username+.error-message', msg) + msg = 'Username "%(username)s" already exists' + msg = msg % {"username": usr} + assertr.element_contains("#username+.error-message", msg) def test_register_special_chars(self): response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': 'xxxaxn', - 'password': 'ąćźżąśśśś', - 'password_confirmation': 'ąćźżąśśśś', - 'email': 'goodmailm@test.plx', - 'firstname': 'test', - 'lastname': 'test' - } + "username": "xxxaxn", + "password": "ąćźżąśśśś", + "password_confirmation": "ąćźżąśśśś", + "email": "goodmailm@test.plx", + "firstname": "test", + "lastname": "test", + }, ) - msg = u'Invalid characters (non-ascii) in password' + msg = "Invalid characters (non-ascii) in password" response.mustcontain(msg) def test_register_password_mismatch(self): response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': 'xs', - 'password': '123qwe', - 'password_confirmation': 'qwe123', - 'email': 'goodmailm@test.plxa', - 'firstname': 'test', - 'lastname': 'test' - } + "username": "xs", + "password": "123qwe", + "password_confirmation": "qwe123", + "email": "goodmailm@test.plxa", + "firstname": "test", + "lastname": "test", + }, ) - msg = u'Passwords do not match' + msg = "Passwords do not match" response.mustcontain(msg) def test_register_ok(self): - username = 'test_regular4' - password = 'qweqwe' - email = 'marcin@test.com' - name = 'testname' - lastname = 'testlastname' + username = "test_regular4" + password = "qweqwe" + email = "marcin@test.com" + name = "testname" + lastname = "testlastname" # this initializes a session - response = self.app.get(route_path('register')) - response.mustcontain('Create an Account') - + response = self.app.get(route_path("register")) + response.mustcontain("Create an Account") response = self.app.post( - route_path('register'), + route_path("register"), { - 'username': username, - 'password': password, - 'password_confirmation': password, - 'email': email, - 'firstname': name, - 'lastname': lastname, - 'admin': True + "username": username, + "password": password, + "password_confirmation": password, + "email": email, + "firstname": name, + "lastname": lastname, + "admin": True, }, - status=302 + status=302, ) # This should be overridden - assert_session_flash( - response, 'You have successfully registered with RhodeCode. You can log-in now.') + assert_session_flash(response, "You have successfully registered with RhodeCode. You can log-in now.") - ret = Session().query(User).filter( - User.username == 'test_regular4').one() + ret = Session().query(User).filter(User.username == "test_regular4").one() assert ret.username == username assert check_password(password, ret.password) assert ret.email == email @@ -411,74 +389,75 @@ class TestLoginController(object): assert not ret.admin def test_forgot_password_wrong_mail(self): - bad_email = 'marcin@wrongmail.org' + bad_email = "marcin@wrongmail.org" # this initializes a session - self.app.get(route_path('reset_password')) + self.app.get(route_path("reset_password")) response = self.app.post( - route_path('reset_password'), {'email': bad_email, } + route_path("reset_password"), + { + "email": bad_email, + }, ) - assert_session_flash(response, - 'If such email exists, a password reset link was sent to it.') + assert_session_flash(response, "If such email exists, a password reset link was sent to it.") def test_forgot_password(self, user_util): # this initializes a session - self.app.get(route_path('reset_password')) + self.app.get(route_path("reset_password")) user = user_util.create_user() user_id = user.user_id email = user.email - response = self.app.post(route_path('reset_password'), {'email': email, }) + response = self.app.post( + route_path("reset_password"), + { + "email": email, + }, + ) - assert_session_flash(response, - 'If such email exists, a password reset link was sent to it.') + assert_session_flash(response, "If such email exists, a password reset link was sent to it.") # BAD KEY - confirm_url = route_path('reset_password_confirmation', params={'key': 'badkey'}) + confirm_url = route_path("reset_password_confirmation", params={"key": "badkey"}) response = self.app.get(confirm_url, status=302) - assert response.location.endswith(route_path('reset_password')) - assert_session_flash(response, 'Given reset token is invalid') + assert response.location.endswith(route_path("reset_password")) + assert_session_flash(response, "Given reset token is invalid") response.follow() # cleanup flash # GOOD KEY - key = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == user_id)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_PASSWORD_RESET)\ + key = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == user_id) + .filter(UserApiKeys.role == UserApiKeys.ROLE_PASSWORD_RESET) .first() + ) assert key - confirm_url = '{}?key={}'.format(route_path('reset_password_confirmation'), key.api_key) + confirm_url = "{}?key={}".format(route_path("reset_password_confirmation"), key.api_key) response = self.app.get(confirm_url) - assert response.status == '302 Found' - assert response.location.endswith(route_path('login')) + assert response.status == "302 Found" + assert response.location.endswith(route_path("login")) - assert_session_flash( - response, - 'Your password reset was successful, ' - 'a new password has been sent to your email') + assert_session_flash(response, "Your password reset was successful, a new password has been sent to your email") response.follow() def _get_api_whitelist(self, values=None): - config = {'api_access_controllers_whitelist': values or []} + config = {"api_access_controllers_whitelist": values or []} return config - @pytest.mark.parametrize("test_name, auth_token", [ - ('none', None), - ('empty_string', ''), - ('fake_number', '123456'), - ('proper_auth_token', None) - ]) - def test_access_not_whitelisted_page_via_auth_token( - self, test_name, auth_token, user_admin): - + @pytest.mark.parametrize( + "test_name, auth_token", + [("none", None), ("empty_string", ""), ("fake_number", "123456"), ("proper_auth_token", None)], + ) + def test_access_not_whitelisted_page_via_auth_token(self, test_name, auth_token, user_admin): whitelist = self._get_api_whitelist([]) - with mock.patch.dict('rhodecode.CONFIG', whitelist): - assert [] == whitelist['api_access_controllers_whitelist'] - if test_name == 'proper_auth_token': + with mock.patch.dict("rhodecode.CONFIG", whitelist): + assert [] == whitelist["api_access_controllers_whitelist"] + if test_name == "proper_auth_token": # use builtin if api_key is None auth_token = user_admin.api_key @@ -488,26 +467,26 @@ class TestLoginController(object): self.app.lint = False self.app.get( - route_path('repo_commit_raw', - repo_name=HG_REPO, commit_id='tip', - params=dict(api_key=auth_token)), - status=302) - - @pytest.mark.parametrize("test_name, auth_token, code", [ - ('none', None, 302), - ('empty_string', '', 302), - ('fake_number', '123456', 302), - ('proper_auth_token', None, 200) - ]) - def test_access_whitelisted_page_via_auth_token( - self, test_name, auth_token, code, user_admin): + route_path("repo_commit_raw", repo_name=HG_REPO, commit_id="tip", params=dict(api_key=auth_token)), + status=302, + ) + @pytest.mark.parametrize( + "test_name, auth_token, code", + [ + ("none", None, 302), + ("empty_string", "", 302), + ("fake_number", "123456", 302), + ("proper_auth_token", None, 200), + ], + ) + def test_access_whitelisted_page_via_auth_token(self, test_name, auth_token, code, user_admin): whitelist = self._get_api_whitelist(whitelist_view) - with mock.patch.dict('rhodecode.CONFIG', whitelist): - assert whitelist_view == whitelist['api_access_controllers_whitelist'] + with mock.patch.dict("rhodecode.CONFIG", whitelist): + assert whitelist_view == whitelist["api_access_controllers_whitelist"] - if test_name == 'proper_auth_token': + if test_name == "proper_auth_token": auth_token = user_admin.api_key assert auth_token @@ -516,67 +495,64 @@ class TestLoginController(object): # and we use memoryview here as a wrapper, quick turn-off self.app.lint = False self.app.get( - route_path('repo_commit_raw', - repo_name=HG_REPO, commit_id='tip', - params=dict(api_key=auth_token)), - status=code) - - @pytest.mark.parametrize("test_name, auth_token, code", [ - ('proper_auth_token', None, 200), - ('wrong_auth_token', '123456', 302), - ]) - def test_access_whitelisted_page_via_auth_token_bound_to_token( - self, test_name, auth_token, code, user_admin): + route_path("repo_commit_raw", repo_name=HG_REPO, commit_id="tip", params=dict(api_key=auth_token)), + status=code, + ) + @pytest.mark.parametrize( + "test_name, auth_token, code", + [ + ("proper_auth_token", None, 200), + ("wrong_auth_token", "123456", 302), + ], + ) + def test_access_whitelisted_page_via_auth_token_bound_to_token(self, test_name, auth_token, code, user_admin): expected_token = auth_token - if test_name == 'proper_auth_token': + if test_name == "proper_auth_token": auth_token = user_admin.api_key expected_token = auth_token assert auth_token - whitelist = self._get_api_whitelist([ - 'RepoCommitsView:repo_commit_raw@{}'.format(expected_token)]) - - with mock.patch.dict('rhodecode.CONFIG', whitelist): + whitelist = self._get_api_whitelist(["RepoCommitsView:repo_commit_raw@{}".format(expected_token)]) + with mock.patch.dict("rhodecode.CONFIG", whitelist): with fixture.anon_access(False): # webtest uses linter to check if response is bytes, # and we use memoryview here as a wrapper, quick turn-off self.app.lint = False self.app.get( - route_path('repo_commit_raw', - repo_name=HG_REPO, commit_id='tip', - params=dict(api_key=auth_token)), - status=code) + route_path("repo_commit_raw", repo_name=HG_REPO, commit_id="tip", params=dict(api_key=auth_token)), + status=code, + ) def test_access_page_via_extra_auth_token(self): whitelist = self._get_api_whitelist(whitelist_view) - with mock.patch.dict('rhodecode.CONFIG', whitelist): - assert whitelist_view == \ - whitelist['api_access_controllers_whitelist'] + with mock.patch.dict("rhodecode.CONFIG", whitelist): + assert whitelist_view == whitelist["api_access_controllers_whitelist"] - new_auth_token = AuthTokenModel().create( - TEST_USER_ADMIN_LOGIN, 'test') + new_auth_token = AuthTokenModel().create(TEST_USER_ADMIN_LOGIN, "test") Session().commit() with fixture.anon_access(False): # webtest uses linter to check if response is bytes, # and we use memoryview here as a wrapper, quick turn-off self.app.lint = False self.app.get( - route_path('repo_commit_raw', - repo_name=HG_REPO, commit_id='tip', - params=dict(api_key=new_auth_token.api_key)), - status=200) + route_path( + "repo_commit_raw", + repo_name=HG_REPO, + commit_id="tip", + params=dict(api_key=new_auth_token.api_key), + ), + status=200, + ) def test_access_page_via_expired_auth_token(self): whitelist = self._get_api_whitelist(whitelist_view) - with mock.patch.dict('rhodecode.CONFIG', whitelist): - assert whitelist_view == \ - whitelist['api_access_controllers_whitelist'] + with mock.patch.dict("rhodecode.CONFIG", whitelist): + assert whitelist_view == whitelist["api_access_controllers_whitelist"] - new_auth_token = AuthTokenModel().create( - TEST_USER_ADMIN_LOGIN, 'test') + new_auth_token = AuthTokenModel().create(TEST_USER_ADMIN_LOGIN, "test") Session().commit() # patch the api key and make it expired new_auth_token.expires = 0 @@ -587,7 +563,11 @@ class TestLoginController(object): # and we use memoryview here as a wrapper, quick turn-off self.app.lint = False self.app.get( - route_path('repo_commit_raw', - repo_name=HG_REPO, commit_id='tip', - params=dict(api_key=new_auth_token.api_key)), - status=302) + route_path( + "repo_commit_raw", + repo_name=HG_REPO, + commit_id="tip", + params=dict(api_key=new_auth_token.api_key), + ), + status=302, + ) diff --git a/rhodecode/apps/login/tests/test_password_reset.py b/rhodecode/apps/login/tests/test_password_reset.py index cd760e2f..5feccd9d 100644 --- a/rhodecode/apps/login/tests/test_password_reset.py +++ b/rhodecode/apps/login/tests/test_password_reset.py @@ -19,9 +19,7 @@ import pytest from rhodecode.lib import helpers as h -from rhodecode.tests import ( - TestController, clear_cache_regions, - TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) +from rhodecode.tests import TestController, clear_cache_regions, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.utils import AssertResponse from rhodecode.tests.routes import route_path @@ -31,64 +29,66 @@ fixture = Fixture() class TestPasswordReset(TestController): - @pytest.mark.parametrize( - 'pwd_reset_setting, show_link, show_reset', [ - ('hg.password_reset.enabled', True, True), - ('hg.password_reset.hidden', False, True), - ('hg.password_reset.disabled', False, False), - ]) - def test_password_reset_settings( - self, pwd_reset_setting, show_link, show_reset): + "pwd_reset_setting, show_link, show_reset", + [ + ("hg.password_reset.enabled", True, True), + ("hg.password_reset.hidden", False, True), + ("hg.password_reset.disabled", False, False), + ], + ) + def test_password_reset_settings(self, pwd_reset_setting, show_link, show_reset): clear_cache_regions() self.log_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) params = { - 'csrf_token': self.csrf_token, - 'anonymous': 'True', - 'default_register': 'hg.register.auto_activate', - 'default_register_message': '', - 'default_password_reset': pwd_reset_setting, - 'default_extern_activate': 'hg.extern_activate.auto', + "csrf_token": self.csrf_token, + "anonymous": "True", + "default_register": "hg.register.auto_activate", + "default_register_message": "", + "default_password_reset": pwd_reset_setting, + "default_extern_activate": "hg.extern_activate.auto", } - resp = self.app.post( - route_path('admin_permissions_application_update'), params=params) + resp = self.app.post(route_path("admin_permissions_application_update"), params=params) self.logout_user() - login_page = self.app.get(route_path('login')) + login_page = self.app.get(route_path("login")) asr_login = AssertResponse(login_page) if show_link: - asr_login.one_element_exists('a.pwd_reset') + asr_login.one_element_exists("a.pwd_reset") else: - asr_login.no_element_exists('a.pwd_reset') + asr_login.no_element_exists("a.pwd_reset") + + response = self.app.get(route_path("reset_password")) - response = self.app.get(route_path('reset_password')) - assert_response = response.assert_response() if show_reset: - response.mustcontain('Send password reset email') - assert_response.one_element_exists('#email') - assert_response.one_element_exists('#send') + response.mustcontain("Send password reset email") + assert_response.one_element_exists("#email") + assert_response.one_element_exists("#send") else: - response.mustcontain('Password reset is disabled.') - assert_response.no_element_exists('#email') - assert_response.no_element_exists('#send') + response.mustcontain("Password reset is disabled.") + assert_response.no_element_exists("#email") + assert_response.no_element_exists("#send") def test_password_form_disabled(self): self.log_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) params = { - 'csrf_token': self.csrf_token, - 'anonymous': 'True', - 'default_register': 'hg.register.auto_activate', - 'default_register_message': '', - 'default_password_reset': 'hg.password_reset.disabled', - 'default_extern_activate': 'hg.extern_activate.auto', + "csrf_token": self.csrf_token, + "anonymous": "True", + "default_register": "hg.register.auto_activate", + "default_register_message": "", + "default_password_reset": "hg.password_reset.disabled", + "default_extern_activate": "hg.extern_activate.auto", } - self.app.post(route_path('admin_permissions_application_update'), params=params) + self.app.post(route_path("admin_permissions_application_update"), params=params) self.logout_user() response = self.app.post( - route_path('reset_password'), {'email': 'lisa@rhodecode.com',} + route_path("reset_password"), + { + "email": "lisa@rhodecode.com", + }, ) response = response.follow() - response.mustcontain('Password reset is disabled.') + response.mustcontain("Password reset is disabled.") diff --git a/rhodecode/apps/login/views.py b/rhodecode/apps/login/views.py index 371cb9a4..c68d50ce 100644 --- a/rhodecode/apps/login/views.py +++ b/rhodecode/apps/login/views.py @@ -81,7 +81,7 @@ def store_user_in_session(session, user_identifier, remember=False): safe_cs = cs.copy() safe_cs["password"] = "****" - log.info("user %s is now authenticated and stored in " "session, session attrs %s", user_identifier, safe_cs) + log.info("user %s is now authenticated and stored in session, session attrs %s", user_identifier, safe_cs) # dumps session attrs back to cookie session._update_cookie_out() @@ -103,7 +103,7 @@ def get_came_from(request): log.error("Suspicious URL scheme detected %s for url %s", parsed.scheme, parsed) came_from = default_came_from elif parsed.netloc and request.host != parsed.netloc: - log.error("Suspicious NETLOC detected %s for url %s server url " "is: %s", parsed.netloc, parsed, request.host) + log.error("Suspicious NETLOC detected %s for url %s server url is: %s", parsed.netloc, parsed, request.host) came_from = default_came_from elif any(bad_char in came_from for bad_char in ("\r", "\n")): log.error("Header injection detected `%s` for url %s server url ", parsed.path, parsed) @@ -365,7 +365,7 @@ class LoginView(BaseAppView): # external auth shouldn't allow password reset if user and user.extern_type != auth_rhodecode.RhodeCodeAuthPlugin.uid: log.warning( - "User %s with external type `%s` tried a password reset. " "This try was rejected", + "User %s with external type `%s` tried a password reset. This try was rejected", user, user.extern_type, ) @@ -436,7 +436,7 @@ class LoginView(BaseAppView): data = {"email": owner.email, "token": token.api_key} UserModel().reset_password(data) h.flash( - _("Your password reset was successful, " "a new password has been sent to your email"), + _("Your password reset was successful, a new password has been sent to your email"), category="success", ) except Exception as e: diff --git a/rhodecode/apps/my_account/__init__.py b/rhodecode/apps/my_account/__init__.py index 99652332..df15d466 100644 --- a/rhodecode/apps/my_account/__init__.py +++ b/rhodecode/apps/my_account/__init__.py @@ -25,346 +25,346 @@ def includeme(config): from rhodecode.apps.my_account.views.my_account_notifications import MyAccountNotificationsView from rhodecode.apps.my_account.views.my_account_ssh_keys import MyAccountSshKeysView - config.add_route( - name='my_account_profile', - pattern=ADMIN_PREFIX + '/my_account/profile') + config.add_route(name="my_account_profile", pattern=ADMIN_PREFIX + "/my_account/profile") config.add_view( MyAccountView, - attr='my_account_profile', - route_name='my_account_profile', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_profile", + route_name="my_account_profile", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) # my account edit details - config.add_route( - name='my_account_edit', - pattern=ADMIN_PREFIX + '/my_account/edit') + config.add_route(name="my_account_edit", pattern=ADMIN_PREFIX + "/my_account/edit") config.add_view( MyAccountView, - attr='my_account_edit', - route_name='my_account_edit', - request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_edit", + route_name="my_account_edit", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) - config.add_route( - name='my_account_update', - pattern=ADMIN_PREFIX + '/my_account/update') + config.add_route(name="my_account_update", pattern=ADMIN_PREFIX + "/my_account/update") config.add_view( MyAccountView, - attr='my_account_update', - route_name='my_account_update', - request_method='POST', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_update", + route_name="my_account_update", + request_method="POST", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) # my account password - config.add_route( - name='my_account_password', - pattern=ADMIN_PREFIX + '/my_account/password') + config.add_route(name="my_account_password", pattern=ADMIN_PREFIX + "/my_account/password") config.add_view( MyAccountView, - attr='my_account_password', - route_name='my_account_password', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_password", + route_name="my_account_password", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) - config.add_route( - name='my_account_password_update', - pattern=ADMIN_PREFIX + '/my_account/password/update') + config.add_route(name="my_account_password_update", pattern=ADMIN_PREFIX + "/my_account/password/update") config.add_view( MyAccountView, - attr='my_account_password_update', - route_name='my_account_password_update', request_method='POST', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_password_update", + route_name="my_account_password_update", + request_method="POST", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) # my account 2fa - config.add_route( - name='my_account_configure_2fa', - pattern=ADMIN_PREFIX + '/my_account/configure_2fa') + config.add_route(name="my_account_configure_2fa", pattern=ADMIN_PREFIX + "/my_account/configure_2fa") config.add_view( MyAccountView, - attr='my_account_2fa', - route_name='my_account_configure_2fa', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_2fa", + route_name="my_account_configure_2fa", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) # my account 2fa save - config.add_route( - name='my_account_configure_2fa_update', - pattern=ADMIN_PREFIX + '/my_account/configure_2fa_update') + config.add_route(name="my_account_configure_2fa_update", pattern=ADMIN_PREFIX + "/my_account/configure_2fa_update") config.add_view( MyAccountView, - attr='my_account_2fa_update', - route_name='my_account_configure_2fa_update', request_method='POST', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_2fa_update", + route_name="my_account_configure_2fa_update", + request_method="POST", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + # my account 2fa recovery code-reset + config.add_route(name="my_account_show_2fa_recovery_codes", pattern=ADMIN_PREFIX + "/my_account/recovery_codes") + config.add_view( + MyAccountView, + attr="my_account_2fa_show_recovery_codes", + route_name="my_account_show_2fa_recovery_codes", + request_method="POST", + xhr=True, + renderer="json_ext", + ) # my account 2fa recovery code-reset config.add_route( - name='my_account_show_2fa_recovery_codes', - pattern=ADMIN_PREFIX + '/my_account/recovery_codes') + name="my_account_regenerate_2fa_recovery_codes", pattern=ADMIN_PREFIX + "/my_account/regenerate_recovery_codes" + ) config.add_view( MyAccountView, - attr='my_account_2fa_show_recovery_codes', - route_name='my_account_show_2fa_recovery_codes', request_method='POST', xhr=True, - renderer='json_ext') - - # my account 2fa recovery code-reset - config.add_route( - name='my_account_regenerate_2fa_recovery_codes', - pattern=ADMIN_PREFIX + '/my_account/regenerate_recovery_codes') - config.add_view( - MyAccountView, - attr='my_account_2fa_regenerate_recovery_codes', - route_name='my_account_regenerate_2fa_recovery_codes', request_method='POST', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_2fa_regenerate_recovery_codes", + route_name="my_account_regenerate_2fa_recovery_codes", + request_method="POST", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) # my account tokens - config.add_route( - name='my_account_auth_tokens', - pattern=ADMIN_PREFIX + '/my_account/auth_tokens') + config.add_route(name="my_account_auth_tokens", pattern=ADMIN_PREFIX + "/my_account/auth_tokens") config.add_view( MyAccountView, - attr='my_account_auth_tokens', - route_name='my_account_auth_tokens', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_auth_tokens", + route_name="my_account_auth_tokens", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) - config.add_route( - name='my_account_auth_tokens_view', - pattern=ADMIN_PREFIX + '/my_account/auth_tokens/view') + config.add_route(name="my_account_auth_tokens_view", pattern=ADMIN_PREFIX + "/my_account/auth_tokens/view") config.add_view( MyAccountView, - attr='my_account_auth_tokens_view', - route_name='my_account_auth_tokens_view', request_method='POST', xhr=True, - renderer='json_ext') + attr="my_account_auth_tokens_view", + route_name="my_account_auth_tokens_view", + request_method="POST", + xhr=True, + renderer="json_ext", + ) - config.add_route( - name='my_account_auth_tokens_add', - pattern=ADMIN_PREFIX + '/my_account/auth_tokens/new') + config.add_route(name="my_account_auth_tokens_add", pattern=ADMIN_PREFIX + "/my_account/auth_tokens/new") config.add_view( - MyAccountView, - attr='my_account_auth_tokens_add', - route_name='my_account_auth_tokens_add', request_method='POST') + MyAccountView, attr="my_account_auth_tokens_add", route_name="my_account_auth_tokens_add", request_method="POST" + ) - config.add_route( - name='my_account_auth_tokens_delete', - pattern=ADMIN_PREFIX + '/my_account/auth_tokens/delete') + config.add_route(name="my_account_auth_tokens_delete", pattern=ADMIN_PREFIX + "/my_account/auth_tokens/delete") config.add_view( MyAccountView, - attr='my_account_auth_tokens_delete', - route_name='my_account_auth_tokens_delete', request_method='POST') + attr="my_account_auth_tokens_delete", + route_name="my_account_auth_tokens_delete", + request_method="POST", + ) # my account ssh keys - config.add_route( - name='my_account_ssh_keys', - pattern=ADMIN_PREFIX + '/my_account/ssh_keys') + config.add_route(name="my_account_ssh_keys", pattern=ADMIN_PREFIX + "/my_account/ssh_keys") config.add_view( MyAccountSshKeysView, - attr='my_account_ssh_keys', - route_name='my_account_ssh_keys', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_ssh_keys", + route_name="my_account_ssh_keys", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) - config.add_route( - name='my_account_ssh_keys_generate', - pattern=ADMIN_PREFIX + '/my_account/ssh_keys/generate') + config.add_route(name="my_account_ssh_keys_generate", pattern=ADMIN_PREFIX + "/my_account/ssh_keys/generate") config.add_view( MyAccountSshKeysView, - attr='ssh_keys_generate_keypair', - route_name='my_account_ssh_keys_generate', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="ssh_keys_generate_keypair", + route_name="my_account_ssh_keys_generate", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) - config.add_route( - name='my_account_ssh_keys_add', - pattern=ADMIN_PREFIX + '/my_account/ssh_keys/new') + config.add_route(name="my_account_ssh_keys_add", pattern=ADMIN_PREFIX + "/my_account/ssh_keys/new") config.add_view( MyAccountSshKeysView, - attr='my_account_ssh_keys_add', - route_name='my_account_ssh_keys_add', request_method='POST',) + attr="my_account_ssh_keys_add", + route_name="my_account_ssh_keys_add", + request_method="POST", + ) - config.add_route( - name='my_account_ssh_keys_delete', - pattern=ADMIN_PREFIX + '/my_account/ssh_keys/delete') + config.add_route(name="my_account_ssh_keys_delete", pattern=ADMIN_PREFIX + "/my_account/ssh_keys/delete") config.add_view( MyAccountSshKeysView, - attr='my_account_ssh_keys_delete', - route_name='my_account_ssh_keys_delete', request_method='POST') + attr="my_account_ssh_keys_delete", + route_name="my_account_ssh_keys_delete", + request_method="POST", + ) # my account user group membership config.add_route( - name='my_account_user_group_membership', - pattern=ADMIN_PREFIX + '/my_account/user_group_membership') + name="my_account_user_group_membership", pattern=ADMIN_PREFIX + "/my_account/user_group_membership" + ) config.add_view( MyAccountView, - attr='my_account_user_group_membership', - route_name='my_account_user_group_membership', - request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_user_group_membership", + route_name="my_account_user_group_membership", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) # my account emails - config.add_route( - name='my_account_emails', - pattern=ADMIN_PREFIX + '/my_account/emails') + config.add_route(name="my_account_emails", pattern=ADMIN_PREFIX + "/my_account/emails") config.add_view( MyAccountView, - attr='my_account_emails', - route_name='my_account_emails', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_emails", + route_name="my_account_emails", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + config.add_route(name="my_account_emails_add", pattern=ADMIN_PREFIX + "/my_account/emails/new") + config.add_view( + MyAccountView, + attr="my_account_emails_add", + route_name="my_account_emails_add", + request_method="POST", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + config.add_route(name="my_account_emails_delete", pattern=ADMIN_PREFIX + "/my_account/emails/delete") + config.add_view( + MyAccountView, attr="my_account_emails_delete", route_name="my_account_emails_delete", request_method="POST" + ) + + config.add_route(name="my_account_repos", pattern=ADMIN_PREFIX + "/my_account/repos") + config.add_view( + MyAccountView, + attr="my_account_repos", + route_name="my_account_repos", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + config.add_route(name="my_account_watched", pattern=ADMIN_PREFIX + "/my_account/watched") + config.add_view( + MyAccountView, + attr="my_account_watched", + route_name="my_account_watched", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + config.add_route(name="my_account_bookmarks", pattern=ADMIN_PREFIX + "/my_account/bookmarks") + config.add_view( + MyAccountView, + attr="my_account_bookmarks", + route_name="my_account_bookmarks", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + config.add_route(name="my_account_bookmarks_update", pattern=ADMIN_PREFIX + "/my_account/bookmarks/update") + config.add_view( + MyAccountView, + attr="my_account_bookmarks_update", + route_name="my_account_bookmarks_update", + request_method="POST", + ) + + config.add_route(name="my_account_goto_bookmark", pattern=ADMIN_PREFIX + "/my_account/bookmark/{bookmark_id}") + config.add_view( + MyAccountView, + attr="my_account_goto_bookmark", + route_name="my_account_goto_bookmark", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + config.add_route(name="my_account_perms", pattern=ADMIN_PREFIX + "/my_account/perms") + config.add_view( + MyAccountView, + attr="my_account_perms", + route_name="my_account_perms", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) + + config.add_route(name="my_account_notifications", pattern=ADMIN_PREFIX + "/my_account/notifications") + config.add_view( + MyAccountView, + attr="my_notifications", + route_name="my_account_notifications", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) config.add_route( - name='my_account_emails_add', - pattern=ADMIN_PREFIX + '/my_account/emails/new') + name="my_account_notifications_toggle_visibility", pattern=ADMIN_PREFIX + "/my_account/toggle_visibility" + ) config.add_view( MyAccountView, - attr='my_account_emails_add', - route_name='my_account_emails_add', request_method='POST', - renderer='rhodecode:templates/admin/my_account/my_account.mako') - - config.add_route( - name='my_account_emails_delete', - pattern=ADMIN_PREFIX + '/my_account/emails/delete') - config.add_view( - MyAccountView, - attr='my_account_emails_delete', - route_name='my_account_emails_delete', request_method='POST') - - config.add_route( - name='my_account_repos', - pattern=ADMIN_PREFIX + '/my_account/repos') - config.add_view( - MyAccountView, - attr='my_account_repos', - route_name='my_account_repos', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') - - config.add_route( - name='my_account_watched', - pattern=ADMIN_PREFIX + '/my_account/watched') - config.add_view( - MyAccountView, - attr='my_account_watched', - route_name='my_account_watched', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') - - config.add_route( - name='my_account_bookmarks', - pattern=ADMIN_PREFIX + '/my_account/bookmarks') - config.add_view( - MyAccountView, - attr='my_account_bookmarks', - route_name='my_account_bookmarks', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') - - config.add_route( - name='my_account_bookmarks_update', - pattern=ADMIN_PREFIX + '/my_account/bookmarks/update') - config.add_view( - MyAccountView, - attr='my_account_bookmarks_update', - route_name='my_account_bookmarks_update', request_method='POST') - - config.add_route( - name='my_account_goto_bookmark', - pattern=ADMIN_PREFIX + '/my_account/bookmark/{bookmark_id}') - config.add_view( - MyAccountView, - attr='my_account_goto_bookmark', - route_name='my_account_goto_bookmark', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') - - config.add_route( - name='my_account_perms', - pattern=ADMIN_PREFIX + '/my_account/perms') - config.add_view( - MyAccountView, - attr='my_account_perms', - route_name='my_account_perms', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') - - config.add_route( - name='my_account_notifications', - pattern=ADMIN_PREFIX + '/my_account/notifications') - config.add_view( - MyAccountView, - attr='my_notifications', - route_name='my_account_notifications', request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') - - config.add_route( - name='my_account_notifications_toggle_visibility', - pattern=ADMIN_PREFIX + '/my_account/toggle_visibility') - config.add_view( - MyAccountView, - attr='my_notifications_toggle_visibility', - route_name='my_account_notifications_toggle_visibility', - request_method='POST', renderer='json_ext') + attr="my_notifications_toggle_visibility", + route_name="my_account_notifications_toggle_visibility", + request_method="POST", + renderer="json_ext", + ) # my account pull requests - config.add_route( - name='my_account_pullrequests', - pattern=ADMIN_PREFIX + '/my_account/pull_requests') + config.add_route(name="my_account_pullrequests", pattern=ADMIN_PREFIX + "/my_account/pull_requests") config.add_view( MyAccountView, - attr='my_account_pullrequests', - route_name='my_account_pullrequests', - request_method='GET', - renderer='rhodecode:templates/admin/my_account/my_account.mako') + attr="my_account_pullrequests", + route_name="my_account_pullrequests", + request_method="GET", + renderer="rhodecode:templates/admin/my_account/my_account.mako", + ) - config.add_route( - name='my_account_pullrequests_data', - pattern=ADMIN_PREFIX + '/my_account/pull_requests/data') + config.add_route(name="my_account_pullrequests_data", pattern=ADMIN_PREFIX + "/my_account/pull_requests/data") config.add_view( MyAccountView, - attr='my_account_pullrequests_data', - route_name='my_account_pullrequests_data', - request_method='GET', renderer='json_ext') + attr="my_account_pullrequests_data", + route_name="my_account_pullrequests_data", + request_method="GET", + renderer="json_ext", + ) # channelstream test config.add_route( - name='my_account_notifications_test_channelstream', - pattern=ADMIN_PREFIX + '/my_account/test_channelstream') + name="my_account_notifications_test_channelstream", pattern=ADMIN_PREFIX + "/my_account/test_channelstream" + ) config.add_view( MyAccountView, - attr='my_account_notifications_test_channelstream', - route_name='my_account_notifications_test_channelstream', - request_method='POST', renderer='json_ext') + attr="my_account_notifications_test_channelstream", + route_name="my_account_notifications_test_channelstream", + request_method="POST", + renderer="json_ext", + ) # notifications - config.add_route( - name='notifications_show_all', - pattern=ADMIN_PREFIX + '/notifications') + config.add_route(name="notifications_show_all", pattern=ADMIN_PREFIX + "/notifications") config.add_view( MyAccountNotificationsView, - attr='notifications_show_all', - route_name='notifications_show_all', request_method='GET', - renderer='rhodecode:templates/admin/notifications/notifications_show_all.mako') + attr="notifications_show_all", + route_name="notifications_show_all", + request_method="GET", + renderer="rhodecode:templates/admin/notifications/notifications_show_all.mako", + ) # notifications - config.add_route( - name='notifications_mark_all_read', - pattern=ADMIN_PREFIX + '/notifications_mark_all_read') + config.add_route(name="notifications_mark_all_read", pattern=ADMIN_PREFIX + "/notifications_mark_all_read") config.add_view( MyAccountNotificationsView, - attr='notifications_mark_all_read', - route_name='notifications_mark_all_read', request_method='POST', - renderer='rhodecode:templates/admin/notifications/notifications_show_all.mako') + attr="notifications_mark_all_read", + route_name="notifications_mark_all_read", + request_method="POST", + renderer="rhodecode:templates/admin/notifications/notifications_show_all.mako", + ) - config.add_route( - name='notifications_show', - pattern=ADMIN_PREFIX + '/notifications/{notification_id}') + config.add_route(name="notifications_show", pattern=ADMIN_PREFIX + "/notifications/{notification_id}") config.add_view( MyAccountNotificationsView, - attr='notifications_show', - route_name='notifications_show', request_method='GET', - renderer='rhodecode:templates/admin/notifications/notifications_show.mako') + attr="notifications_show", + route_name="notifications_show", + request_method="GET", + renderer="rhodecode:templates/admin/notifications/notifications_show.mako", + ) - config.add_route( - name='notifications_update', - pattern=ADMIN_PREFIX + '/notifications/{notification_id}/update') + config.add_route(name="notifications_update", pattern=ADMIN_PREFIX + "/notifications/{notification_id}/update") config.add_view( MyAccountNotificationsView, - attr='notification_update', - route_name='notifications_update', request_method='POST', - renderer='json_ext') + attr="notification_update", + route_name="notifications_update", + request_method="POST", + renderer="json_ext", + ) - config.add_route( - name='notifications_delete', - pattern=ADMIN_PREFIX + '/notifications/{notification_id}/delete') + config.add_route(name="notifications_delete", pattern=ADMIN_PREFIX + "/notifications/{notification_id}/delete") config.add_view( MyAccountNotificationsView, - attr='notification_delete', - route_name='notifications_delete', request_method='POST', - renderer='json_ext') + attr="notification_delete", + route_name="notifications_delete", + request_method="POST", + renderer="json_ext", + ) diff --git a/rhodecode/apps/my_account/tests/test_my_account_auth_tokens.py b/rhodecode/apps/my_account/tests/test_my_account_auth_tokens.py index cb483345..4dc627eb 100644 --- a/rhodecode/apps/my_account/tests/test_my_account_auth_tokens.py +++ b/rhodecode/apps/my_account/tests/test_my_account_auth_tokens.py @@ -20,8 +20,7 @@ import pytest from rhodecode.apps._base import ADMIN_PREFIX from rhodecode.model.db import User -from rhodecode.tests import ( - TestController, assert_session_flash) +from rhodecode.tests import TestController, assert_session_flash from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -30,38 +29,38 @@ fixture = Fixture() class TestMyAccountAuthTokens(TestController): - def test_my_account_auth_tokens(self): - usr = self.log_user('test_regular2', 'test12') - user = User.get(usr['user_id']) - response = self.app.get(route_path('my_account_auth_tokens')) + usr = self.log_user("test_regular2", "test12") + user = User.get(usr["user_id"]) + response = self.app.get(route_path("my_account_auth_tokens")) for token in user.auth_tokens: response.mustcontain(token[:4]) - response.mustcontain('never') + response.mustcontain("never") def test_my_account_add_auth_tokens_wrong_csrf(self, user_util): - user = user_util.create_user(password='qweqwe') - self.log_user(user.username, 'qweqwe') + user = user_util.create_user(password="qweqwe") + self.log_user(user.username, "qweqwe") - self.app.post( - route_path('my_account_auth_tokens_add'), - {'description': 'desc', 'lifetime': -1}, status=403) + self.app.post(route_path("my_account_auth_tokens_add"), {"description": "desc", "lifetime": -1}, status=403) - @pytest.mark.parametrize("desc, lifetime", [ - ('forever', -1), - ('5mins', 60*5), - ('30days', 60*60*24*30), - ]) + @pytest.mark.parametrize( + "desc, lifetime", + [ + ("forever", -1), + ("5mins", 60 * 5), + ("30days", 60 * 60 * 24 * 30), + ], + ) def test_my_account_add_auth_tokens(self, desc, lifetime, user_util): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") user_id = user.user_id - self.log_user(user.username, 'qweqwe') + self.log_user(user.username, "qweqwe") response = self.app.post( - route_path('my_account_auth_tokens_add'), - {'description': desc, 'lifetime': lifetime, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Auth token successfully created') + route_path("my_account_auth_tokens_add"), + {"description": desc, "lifetime": lifetime, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Auth token successfully created") response = response.follow() user = User.get(user_id) @@ -69,19 +68,19 @@ class TestMyAccountAuthTokens(TestController): response.mustcontain(auth_token[:4]) def test_my_account_delete_auth_token(self, user_util): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") user_id = user.user_id - self.log_user(user.username, 'qweqwe') + self.log_user(user.username, "qweqwe") user = User.get(user_id) keys = user.get_auth_tokens() assert 2 == len(keys) response = self.app.post( - route_path('my_account_auth_tokens_add'), - {'description': 'desc', 'lifetime': -1, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Auth token successfully created') + route_path("my_account_auth_tokens_add"), + {"description": "desc", "lifetime": -1, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Auth token successfully created") response.follow() user = User.get(user_id) @@ -89,9 +88,10 @@ class TestMyAccountAuthTokens(TestController): assert 3 == len(keys) response = self.app.post( - route_path('my_account_auth_tokens_delete'), - {'del_auth_token': keys[0].user_api_key_id, 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Auth token successfully deleted') + route_path("my_account_auth_tokens_delete"), + {"del_auth_token": keys[0].user_api_key_id, "csrf_token": self.csrf_token}, + ) + assert_session_flash(response, "Auth token successfully deleted") user = User.get(user_id) keys = user.auth_tokens diff --git a/rhodecode/apps/my_account/tests/test_my_account_edit.py b/rhodecode/apps/my_account/tests/test_my_account_edit.py index 9d0552c0..5c189ba2 100644 --- a/rhodecode/apps/my_account/tests/test_my_account_edit.py +++ b/rhodecode/apps/my_account/tests/test_my_account_edit.py @@ -24,148 +24,140 @@ from rhodecode.tests.routes import route_path class TestMyAccountEdit(TestController): - def test_my_account_edit(self): self.log_user() - response = self.app.get(route_path('my_account_edit')) + response = self.app.get(route_path("my_account_edit")) response.mustcontain('value="test_admin') @pytest.mark.backends("git", "hg") def test_my_account_my_pullrequests(self, pr_util): self.log_user() - response = self.app.get(route_path('my_account_pullrequests')) - response.mustcontain('There are currently no open pull ' - 'requests requiring your participation.') + response = self.app.get(route_path("my_account_pullrequests")) + response.mustcontain("There are currently no open pull requests requiring your participation.") @pytest.mark.backends("git", "hg") - @pytest.mark.parametrize('params, expected_title', [ - ({'closed': 1}, 'Closed'), - ({'awaiting_my_review': 1}, 'Awaiting my review'), - ]) + @pytest.mark.parametrize( + "params, expected_title", + [ + ({"closed": 1}, "Closed"), + ({"awaiting_my_review": 1}, "Awaiting my review"), + ], + ) def test_my_account_my_pullrequests_data(self, pr_util, xhr_header, params, expected_title): self.log_user() - response = self.app.get(route_path('my_account_pullrequests_data'), - extra_environ=xhr_header) - assert response.json == { - 'data': [], 'draw': None, - 'recordsFiltered': 0, 'recordsTotal': 0} + response = self.app.get(route_path("my_account_pullrequests_data"), extra_environ=xhr_header) + assert response.json == {"data": [], "draw": None, "recordsFiltered": 0, "recordsTotal": 0} - pr = pr_util.create_pull_request(title='TestMyAccountPR') - expected = { - 'author_raw': 'RhodeCode Admin', - 'name_raw': pr.pull_request_id - } - response = self.app.get(route_path('my_account_pullrequests_data'), - extra_environ=xhr_header) - assert response.json['recordsTotal'] == 1 - assert response.json['data'][0]['author_raw'] == expected['author_raw'] + pr = pr_util.create_pull_request(title="TestMyAccountPR") + expected = {"author_raw": "RhodeCode Admin", "name_raw": pr.pull_request_id} + response = self.app.get(route_path("my_account_pullrequests_data"), extra_environ=xhr_header) + assert response.json["recordsTotal"] == 1 + assert response.json["data"][0]["author_raw"] == expected["author_raw"] - assert response.json['data'][0]['author_raw'] == expected['author_raw'] - assert response.json['data'][0]['name_raw'] == expected['name_raw'] + assert response.json["data"][0]["author_raw"] == expected["author_raw"] + assert response.json["data"][0]["name_raw"] == expected["name_raw"] @pytest.mark.parametrize( - "name, attrs", [ - ('firstname', {'firstname': 'new_username'}), - ('lastname', {'lastname': 'new_username'}), - ('admin', {'admin': True}), - ('admin', {'admin': False}), - ('extern_type', {'extern_type': 'ldap'}), - ('extern_type', {'extern_type': None}), + "name, attrs", + [ + ("firstname", {"firstname": "new_username"}), + ("lastname", {"lastname": "new_username"}), + ("admin", {"admin": True}), + ("admin", {"admin": False}), + ("extern_type", {"extern_type": "ldap"}), + ("extern_type", {"extern_type": None}), # ('extern_name', {'extern_name': 'test'}), # ('extern_name', {'extern_name': None}), - ('active', {'active': False}), - ('active', {'active': True}), - ('email', {'email': 'some@email.com'}), - ]) + ("active", {"active": False}), + ("active", {"active": True}), + ("email", {"email": "some@email.com"}), + ], + ) def test_my_account_update(self, name, attrs, user_util): - usr = user_util.create_user(password='qweqwe') + usr = user_util.create_user(password="qweqwe") params = usr.get_api_data() # current user data user_id = usr.user_id - self.log_user( - username=usr.username, password='qweqwe') + self.log_user(username=usr.username, password="qweqwe") - params.update({'password_confirmation': ''}) - params.update({'new_password': ''}) - params.update({'extern_type': 'rhodecode'}) - params.update({'extern_name': 'rhodecode'}) - params.update({'csrf_token': self.csrf_token}) + params.update({"password_confirmation": ""}) + params.update({"new_password": ""}) + params.update({"extern_type": "rhodecode"}) + params.update({"extern_name": "rhodecode"}) + params.update({"csrf_token": self.csrf_token}) params.update(attrs) # my account page cannot set language param yet, only for admins - del params['language'] - if name == 'email': - uem = user_util.create_additional_user_email(usr, attrs['email']) + del params["language"] + if name == "email": + uem = user_util.create_additional_user_email(usr, attrs["email"]) email_before = User.get(user_id).email - response = self.app.post(route_path('my_account_update'), params) + response = self.app.post(route_path("my_account_update"), params) - assert_session_flash( - response, 'Your account was updated successfully') + assert_session_flash(response, "Your account was updated successfully") - del params['csrf_token'] + del params["csrf_token"] updated_user = User.get(user_id) updated_params = updated_user.get_api_data() - updated_params.update({'password_confirmation': ''}) - updated_params.update({'new_password': ''}) + updated_params.update({"password_confirmation": ""}) + updated_params.update({"new_password": ""}) - params['last_login'] = updated_params['last_login'] - params['last_activity'] = updated_params['last_activity'] + params["last_login"] = updated_params["last_login"] + params["last_activity"] = updated_params["last_activity"] # my account page cannot set language param yet, only for admins # but we get this info from API anyway - params['language'] = updated_params['language'] + params["language"] = updated_params["language"] - if name == 'email': - params['emails'] = [attrs['email'], email_before] - if name == 'extern_type': + if name == "email": + params["emails"] = [attrs["email"], email_before] + if name == "extern_type": # cannot update this via form, expected value is original one - params['extern_type'] = "rhodecode" - if name == 'extern_name': + params["extern_type"] = "rhodecode" + if name == "extern_name": # cannot update this via form, expected value is original one - params['extern_name'] = str(user_id) - if name == 'active': + params["extern_name"] = str(user_id) + if name == "active": # my account cannot deactivate account - params['active'] = True - if name == 'admin': + params["active"] = True + if name == "admin": # my account cannot make you an admin ! - params['admin'] = False + params["admin"] = False assert params == updated_params def test_my_account_update_err_email_not_exists_in_emails(self): self.log_user() - new_email = 'test_regular@mail.com' # not in emails + new_email = "test_regular@mail.com" # not in emails params = { - 'username': 'test_admin', - 'new_password': 'test12', - 'password_confirmation': 'test122', - 'firstname': 'NewName', - 'lastname': 'NewLastname', - 'email': new_email, - 'csrf_token': self.csrf_token, + "username": "test_admin", + "new_password": "test12", + "password_confirmation": "test122", + "firstname": "NewName", + "lastname": "NewLastname", + "email": new_email, + "csrf_token": self.csrf_token, } - response = self.app.post(route_path('my_account_update'), - params=params) + response = self.app.post(route_path("my_account_update"), params=params) response.mustcontain('"test_regular@mail.com" is not one of test_admin@mail.com') def test_my_account_update_bad_email_address(self): - self.log_user('test_regular2', 'test12') + self.log_user("test_regular2", "test12") - new_email = 'newmail.pl' + new_email = "newmail.pl" params = { - 'username': 'test_admin', - 'new_password': 'test12', - 'password_confirmation': 'test122', - 'firstname': 'NewName', - 'lastname': 'NewLastname', - 'email': new_email, - 'csrf_token': self.csrf_token, + "username": "test_admin", + "new_password": "test12", + "password_confirmation": "test122", + "firstname": "NewName", + "lastname": "NewLastname", + "email": new_email, + "csrf_token": self.csrf_token, } - response = self.app.post(route_path('my_account_update'), - params=params) + response = self.app.post(route_path("my_account_update"), params=params) response.mustcontain('"newmail.pl" is not one of test_regular2@mail.com') diff --git a/rhodecode/apps/my_account/tests/test_my_account_emails.py b/rhodecode/apps/my_account/tests/test_my_account_emails.py index 7888bd73..152ff7ac 100644 --- a/rhodecode/apps/my_account/tests/test_my_account_emails.py +++ b/rhodecode/apps/my_account/tests/test_my_account_emails.py @@ -21,8 +21,12 @@ import pytest from rhodecode.apps._base import ADMIN_PREFIX from rhodecode.model.db import User, UserEmailMap from rhodecode.tests import ( - TestController, TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_EMAIL, - assert_session_flash, TEST_USER_REGULAR_PASS) + TestController, + TEST_USER_ADMIN_LOGIN, + TEST_USER_REGULAR_EMAIL, + assert_session_flash, + TEST_USER_REGULAR_PASS, +) from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -33,34 +37,35 @@ fixture = Fixture() class TestMyAccountEmails(TestController): def test_my_account_my_emails(self): self.log_user() - response = self.app.get(route_path('my_account_emails')) - response.mustcontain('No additional emails specified') + response = self.app.get(route_path("my_account_emails")) + response.mustcontain("No additional emails specified") def test_my_account_my_emails_add_remove(self): self.log_user() - response = self.app.get(route_path('my_account_emails')) - response.mustcontain('No additional emails specified') - - response = self.app.post(route_path('my_account_emails_add'), - {'email': 'foo@barz.com', - 'current_password': TEST_USER_REGULAR_PASS, - 'csrf_token': self.csrf_token}) - - response = self.app.get(route_path('my_account_emails')) - - email_id = UserEmailMap.query().filter( - UserEmailMap.user == User.get_by_username( - TEST_USER_ADMIN_LOGIN)).filter( - UserEmailMap.email == 'foo@barz.com').one().email_id - - response.mustcontain('foo@barz.com') - response.mustcontain('' % email_id) + response = self.app.get(route_path("my_account_emails")) + response.mustcontain("No additional emails specified") response = self.app.post( - route_path('my_account_emails_delete'), { - 'del_email_id': email_id, - 'csrf_token': self.csrf_token}) - assert_session_flash(response, 'Email successfully deleted') - response = self.app.get(route_path('my_account_emails')) - response.mustcontain('No additional emails specified') + route_path("my_account_emails_add"), + {"email": "foo@barz.com", "current_password": TEST_USER_REGULAR_PASS, "csrf_token": self.csrf_token}, + ) + + response = self.app.get(route_path("my_account_emails")) + + email_id = ( + UserEmailMap.query() + .filter(UserEmailMap.user == User.get_by_username(TEST_USER_ADMIN_LOGIN)) + .filter(UserEmailMap.email == "foo@barz.com") + .one() + .email_id + ) + + response.mustcontain("foo@barz.com") + response.mustcontain('' % email_id) + + response = self.app.post( + route_path("my_account_emails_delete"), {"del_email_id": email_id, "csrf_token": self.csrf_token} + ) + assert_session_flash(response, "Email successfully deleted") + response = self.app.get(route_path("my_account_emails")) + response.mustcontain("No additional emails specified") diff --git a/rhodecode/apps/my_account/tests/test_my_account_notifications.py b/rhodecode/apps/my_account/tests/test_my_account_notifications.py index 6c3e5dd9..81d00075 100644 --- a/rhodecode/apps/my_account/tests/test_my_account_notifications.py +++ b/rhodecode/apps/my_account/tests/test_my_account_notifications.py @@ -19,8 +19,12 @@ import pytest from rhodecode.tests import ( - TestController, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, - TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) + TestController, + TEST_USER_REGULAR_LOGIN, + TEST_USER_REGULAR_PASS, + TEST_USER_ADMIN_LOGIN, + TEST_USER_ADMIN_PASS, +) from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -32,7 +36,6 @@ fixture = Fixture() class TestNotificationsController(TestController): - def teardown_method(self, method): for n in Notification.query().all(): inst = Notification.get(n.notification_id) @@ -40,63 +43,64 @@ class TestNotificationsController(TestController): Session().commit() def test_mark_all_read(self, user_util): - user = user_util.create_user(password='qweqwe') - self.log_user(user.username, 'qweqwe') + user = user_util.create_user(password="qweqwe") + self.log_user(user.username, "qweqwe") - self.app.post( - route_path('notifications_mark_all_read'), status=302, - params={'csrf_token': self.csrf_token} - ) + self.app.post(route_path("notifications_mark_all_read"), status=302, params={"csrf_token": self.csrf_token}) def test_show_all(self, user_util): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") user_id = user.user_id - self.log_user(user.username, 'qweqwe') + self.log_user(user.username, "qweqwe") - response = self.app.get( - route_path('notifications_show_all', params={'type': 'all'})) - response.mustcontain( - '
No notifications here yet
') + response = self.app.get(route_path("notifications_show_all", params={"type": "all"})) + response.mustcontain('
No notifications here yet
') notification = NotificationModel().create( - created_by=user_id, notification_subject=u'test_notification_1', - notification_body=u'notification_1', recipients=[user_id]) + created_by=user_id, + notification_subject="test_notification_1", + notification_body="notification_1", + recipients=[user_id], + ) Session().commit() notification_id = notification.notification_id - response = self.app.get(route_path('notifications_show_all', - params={'type': 'all'})) + response = self.app.get(route_path("notifications_show_all", params={"type": "all"})) response.mustcontain('id="notification_%s"' % notification_id) def test_show_unread(self, user_util): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") user_id = user.user_id - self.log_user(user.username, 'qweqwe') + self.log_user(user.username, "qweqwe") - response = self.app.get(route_path('notifications_show_all')) - response.mustcontain( - '
No notifications here yet
') + response = self.app.get(route_path("notifications_show_all")) + response.mustcontain('
No notifications here yet
') notification = NotificationModel().create( - created_by=user_id, notification_subject=u'test_notification_1', - notification_body=u'notification_1', recipients=[user_id]) + created_by=user_id, + notification_subject="test_notification_1", + notification_body="notification_1", + recipients=[user_id], + ) # mark the USER notification as unread - user_notification = NotificationModel().get_user_notification( - user_id, notification) + user_notification = NotificationModel().get_user_notification(user_id, notification) user_notification.read = False Session().commit() notification_id = notification.notification_id - response = self.app.get(route_path('notifications_show_all')) + response = self.app.get(route_path("notifications_show_all")) response.mustcontain('id="notification_%s"' % notification_id) response.mustcontain('
"{}" is not one of -1'.format( - group.group_id)) + csrf_token=csrf_token, + ), + status=200, + ) + response.mustcontain('"{}" is not one of -1'.format(group.group_id)) diff --git a/rhodecode/apps/repo_group/views/__init__.py b/rhodecode/apps/repo_group/views/__init__.py index f3a2879b..e786a1a1 100644 --- a/rhodecode/apps/repo_group/views/__init__.py +++ b/rhodecode/apps/repo_group/views/__init__.py @@ -14,4 +14,4 @@ # # This program is dual-licensed. If you wish to learn more about the # RhodeCode Enterprise Edition, including its added features, Support services, -# and proprietary license terms, please see https://rhodecode.com/licenses/ \ No newline at end of file +# and proprietary license terms, please see https://rhodecode.com/licenses/ diff --git a/rhodecode/apps/repo_group/views/repo_group_advanced.py b/rhodecode/apps/repo_group/views/repo_group_advanced.py index a9968bb5..310802b4 100644 --- a/rhodecode/apps/repo_group/views/repo_group_advanced.py +++ b/rhodecode/apps/repo_group/views/repo_group_advanced.py @@ -24,8 +24,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import RepoGroupAppView from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger -from rhodecode.lib.auth import ( - LoginRequired, CSRFRequired, HasRepoGroupPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, CSRFRequired, HasRepoGroupPermissionAnyDecorator from rhodecode.model.repo_group import RepoGroupModel from rhodecode.model.meta import Session @@ -38,22 +37,22 @@ class RepoGroupAdvancedSettingsView(RepoGroupAppView): return c @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") def edit_repo_group_advanced(self): _ = self.request.translate c = self.load_default_context() - c.active = 'advanced' + c.active = "advanced" c.repo_group = self.db_repo_group # update commit cache if GET flag is present - if self.request.GET.get('update_commit_cache'): + if self.request.GET.get("update_commit_cache"): self.db_repo_group.update_commit_cache() - h.flash(_('updated commit cache'), category='success') + h.flash(_("updated commit cache"), category="success") return self._get_template_context(c) @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") @CSRFRequired() def edit_repo_group_delete(self): _ = self.request.translate @@ -64,40 +63,35 @@ class RepoGroupAdvancedSettingsView(RepoGroupAppView): repos = c.repo_group.repositories.all() if repos: msg = _ungettext( - 'This repository group contains %(num)d repository and cannot be deleted', - 'This repository group contains %(num)d repositories and cannot be' - ' deleted', - len(repos)) % {'num': len(repos)} - h.flash(msg, category='warning') - raise HTTPFound( - h.route_path('edit_repo_group_advanced', - repo_group_name=self.db_repo_group_name)) + "This repository group contains %(num)d repository and cannot be deleted", + "This repository group contains %(num)d repositories and cannot be deleted", + len(repos), + ) % {"num": len(repos)} + h.flash(msg, category="warning") + raise HTTPFound(h.route_path("edit_repo_group_advanced", repo_group_name=self.db_repo_group_name)) children = c.repo_group.children.all() if children: msg = _ungettext( - 'This repository group contains %(num)d subgroup and cannot be deleted', - 'This repository group contains %(num)d subgroups and cannot be deleted', - len(children)) % {'num': len(children)} - h.flash(msg, category='warning') - raise HTTPFound( - h.route_path('edit_repo_group_advanced', - repo_group_name=self.db_repo_group_name)) + "This repository group contains %(num)d subgroup and cannot be deleted", + "This repository group contains %(num)d subgroups and cannot be deleted", + len(children), + ) % {"num": len(children)} + h.flash(msg, category="warning") + raise HTTPFound(h.route_path("edit_repo_group_advanced", repo_group_name=self.db_repo_group_name)) try: old_values = c.repo_group.get_api_data() RepoGroupModel().delete(self.db_repo_group_name) - audit_logger.store_web( - 'repo_group.delete', action_data={'old_data': old_values}, - user=c.rhodecode_user) + audit_logger.store_web("repo_group.delete", action_data={"old_data": old_values}, user=c.rhodecode_user) Session().commit() - h.flash(_('Removed repository group `%s`') % self.db_repo_group_name, - category='success') + h.flash(_("Removed repository group `%s`") % self.db_repo_group_name, category="success") except Exception: log.exception("Exception during deletion of repository group") - h.flash(_('Error occurred during deletion of repository group %s') - % self.db_repo_group_name, category='error') + h.flash( + _("Error occurred during deletion of repository group %s") % self.db_repo_group_name, category="error" + ) - raise HTTPFound(h.route_path('repo_groups')) + raise HTTPFound(h.route_path("repo_groups")) diff --git a/rhodecode/apps/repo_group/views/repo_group_permissions.py b/rhodecode/apps/repo_group/views/repo_group_permissions.py index df47f553..2591ba8f 100644 --- a/rhodecode/apps/repo_group/views/repo_group_permissions.py +++ b/rhodecode/apps/repo_group/views/repo_group_permissions.py @@ -24,8 +24,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import RepoGroupAppView from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger -from rhodecode.lib.auth import ( - LoginRequired, HasRepoGroupPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoGroupPermissionAnyDecorator, CSRFRequired from rhodecode.model.db import User from rhodecode.model.permission import PermissionModel from rhodecode.model.repo_group import RepoGroupModel @@ -42,61 +41,52 @@ class RepoGroupPermissionsView(RepoGroupAppView): return c @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") def edit_repo_group_permissions(self): c = self.load_default_context() - c.active = 'permissions' + c.active = "permissions" c.repo_group = self.db_repo_group return self._get_template_context(c) @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") @CSRFRequired() def edit_repo_groups_permissions_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'perms' + c.active = "perms" c.repo_group = self.db_repo_group - valid_recursive_choices = ['none', 'repos', 'groups', 'all'] - form = RepoGroupPermsForm(self.request.translate, valid_recursive_choices)()\ - .to_python(self.request.POST) + valid_recursive_choices = ["none", "repos", "groups", "all"] + form = RepoGroupPermsForm(self.request.translate, valid_recursive_choices)().to_python(self.request.POST) if not c.rhodecode_user.is_admin: if self._revoke_perms_on_yourself(form): - msg = _('Cannot change permission for yourself as admin') - h.flash(msg, category='warning') - raise HTTPFound( - h.route_path('edit_repo_group_perms', - repo_group_name=self.db_repo_group_name)) + msg = _("Cannot change permission for yourself as admin") + h.flash(msg, category="warning") + raise HTTPFound(h.route_path("edit_repo_group_perms", repo_group_name=self.db_repo_group_name)) # iterate over all members(if in recursive mode) of this groups and # set the permissions ! # this can be potentially heavy operation changes = RepoGroupModel().update_permissions( - c.repo_group, - form['perm_additions'], form['perm_updates'], form['perm_deletions'], - form['recursive']) + c.repo_group, form["perm_additions"], form["perm_updates"], form["perm_deletions"], form["recursive"] + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_web( - 'repo_group.edit.permissions', action_data=action_data, - user=c.rhodecode_user) + audit_logger.store_web("repo_group.edit.permissions", action_data=action_data, user=c.rhodecode_user) Session().commit() - h.flash(_('Repository Group permissions updated'), category='success') + h.flash(_("Repository Group permissions updated"), category="success") affected_user_ids = None - if changes.get('default_user_changed', False): + if changes.get("default_user_changed", False): # if we change the default user, we need to flush everyone permissions affected_user_ids = User.get_all_user_ids() - PermissionModel().flush_user_permission_caches( - changes, affected_user_ids=affected_user_ids) + PermissionModel().flush_user_permission_caches(changes, affected_user_ids=affected_user_ids) - raise HTTPFound( - h.route_path('edit_repo_group_perms', - repo_group_name=self.db_repo_group_name)) + raise HTTPFound(h.route_path("edit_repo_group_perms", repo_group_name=self.db_repo_group_name)) diff --git a/rhodecode/apps/repo_group/views/repo_group_settings.py b/rhodecode/apps/repo_group/views/repo_group_settings.py index 036365e7..c4bdfc0f 100644 --- a/rhodecode/apps/repo_group/views/repo_group_settings.py +++ b/rhodecode/apps/repo_group/views/repo_group_settings.py @@ -28,8 +28,12 @@ from rhodecode.forms import RcForm from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAll, - HasRepoGroupPermissionAny, HasRepoGroupPermissionAnyDecorator, CSRFRequired) + LoginRequired, + HasPermissionAll, + HasRepoGroupPermissionAny, + HasRepoGroupPermissionAnyDecorator, + CSRFRequired, +) from rhodecode.model.db import Session, RepoGroup, User from rhodecode.model.permission import PermissionModel from rhodecode.model.scm import RepoGroupList @@ -53,12 +57,8 @@ class RepoGroupSettingsView(RepoGroupAppView): # creation in root show_root_location = True - acl_groups = RepoGroupList( - RepoGroup.query().all(), - perm_set=['group.admin']) - c.repo_groups = RepoGroup.groups_choices( - groups=acl_groups, - show_empty_group=show_root_location) + acl_groups = RepoGroupList(RepoGroup.query().all(), perm_set=["group.admin"]) + c.repo_groups = RepoGroup.groups_choices(groups=acl_groups, show_empty_group=show_root_location) # filter out current repo group exclude_group_ids = [c.repo_group.group_id] c.repo_groups = [x for x in c.repo_groups if x[0] not in exclude_group_ids] @@ -66,17 +66,15 @@ class RepoGroupSettingsView(RepoGroupAppView): parent_group = c.repo_group.parent_group - add_parent_group = (parent_group and ( - parent_group.group_id not in c.repo_groups_choices)) + add_parent_group = parent_group and (parent_group.group_id not in c.repo_groups_choices) if add_parent_group: c.repo_groups_choices.append(parent_group.group_id) c.repo_groups.append(RepoGroup._generate_choice(parent_group)) return c def _can_create_repo_group(self, parent_group_id=None): - is_admin = HasPermissionAll('hg.admin')('group create controller') - create_repo_group = HasPermissionAll( - 'hg.repogroup.create.true')('group create controller') + is_admin = HasPermissionAll("hg.admin")("group create controller") + create_repo_group = HasPermissionAll("hg.repogroup.create.true")("group create controller") if is_admin or (create_repo_group and not parent_group_id): # we're global admin, or we have global repo group create # permission @@ -86,8 +84,7 @@ class RepoGroupSettingsView(RepoGroupAppView): # we check the permission if we can write to parent group group = RepoGroup.get(parent_group_id) group_name = group.group_name if group else None - if HasRepoGroupPermissionAny('group.admin')( - group_name, 'check if user is an admin of group'): + if HasRepoGroupPermissionAny("group.admin")(group_name, "check if user is an admin of group"): # we're an admin of passed in group, we're ok. return True else: @@ -98,32 +95,31 @@ class RepoGroupSettingsView(RepoGroupAppView): return repo_group_schema.RepoGroupSettingsSchema().bind( repo_group_repo_group_options=c.repo_groups_choices, repo_group_repo_group_items=c.repo_groups, - # user caller user=self._rhodecode_user, - old_values=old_values + old_values=old_values, ) @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") def edit_settings(self): c = self.load_default_context() - c.active = 'settings' + c.active = "settings" defaults = RepoGroupModel()._get_defaults(self.db_repo_group_name) - defaults['repo_group_owner'] = defaults['user'] + defaults["repo_group_owner"] = defaults["user"] schema = self._get_schema(c) c.form = RcForm(schema, appstruct=defaults) return self._get_template_context(c) @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") @CSRFRequired() def edit_settings_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'settings' + c.active = "settings" old_repo_group_name = self.db_repo_group_name new_repo_group_name = old_repo_group_name @@ -142,44 +138,39 @@ class RepoGroupSettingsView(RepoGroupAppView): # data is now VALID, proceed with updates # save validated data back into the updates dict validated_updates = dict( - group_name=schema_data['repo_group']['repo_group_name_without_group'], - group_parent_id=schema_data['repo_group']['repo_group_id'], - user=schema_data['repo_group_owner'], - group_description=schema_data['repo_group_description'], - enable_locking=schema_data['repo_group_enable_locking'], + group_name=schema_data["repo_group"]["repo_group_name_without_group"], + group_parent_id=schema_data["repo_group"]["repo_group_id"], + user=schema_data["repo_group_owner"], + group_description=schema_data["repo_group_description"], + enable_locking=schema_data["repo_group_enable_locking"], ) try: RepoGroupModel().update(self.db_repo_group, validated_updates) - audit_logger.store_web( - 'repo_group.edit', action_data={'old_data': old_values}, - user=c.rhodecode_user) + audit_logger.store_web("repo_group.edit", action_data={"old_data": old_values}, user=c.rhodecode_user) Session().commit() # use the new full name for redirect once we know we updated # the name on filesystem and in DB - new_repo_group_name = schema_data['repo_group']['repo_group_name_with_group'] + new_repo_group_name = schema_data["repo_group"]["repo_group_name_with_group"] - h.flash(_('Repository Group `{}` updated successfully').format( - old_repo_group_name), category='success') + h.flash(_("Repository Group `{}` updated successfully").format(old_repo_group_name), category="success") except Exception: log.exception("Exception during update or repository group") - h.flash(_('Error occurred during update of repository group %s') - % old_repo_group_name, category='error') + h.flash(_("Error occurred during update of repository group %s") % old_repo_group_name, category="error") name_changed = old_repo_group_name != new_repo_group_name if name_changed: current_perms = self.db_repo_group.permissions(expand_from_user_groups=True) - affected_user_ids = [perm['user_id'] for perm in current_perms] + affected_user_ids = [perm["user_id"] for perm in current_perms] # NOTE(marcink): also add owner maybe it has changed - owner = User.get_by_username(schema_data['repo_group_owner']) + owner = User.get_by_username(schema_data["repo_group_owner"]) owner_id = owner.user_id if owner else self._rhodecode_user.user_id affected_user_ids.extend([self._rhodecode_user.user_id, owner_id]) PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound( - h.route_path('edit_repo_group', repo_group_name=new_repo_group_name)) + raise HTTPFound(h.route_path("edit_repo_group", repo_group_name=new_repo_group_name)) diff --git a/rhodecode/apps/repository/__init__.py b/rhodecode/apps/repository/__init__.py index 42453689..1a4650df 100644 --- a/rhodecode/apps/repository/__init__.py +++ b/rhodecode/apps/repository/__init__.py @@ -48,1197 +48,1351 @@ def includeme(config): from rhodecode.apps.repository.views.repo_tags import RepoTagsView # repo creating checks, special cases that aren't repo routes - config.add_route( - name='repo_creating', - pattern='/{repo_name:.*?[^/]}/repo_creating') + config.add_route(name="repo_creating", pattern="/{repo_name:.*?[^/]}/repo_creating") config.add_view( RepoChecksView, - attr='repo_creating', - route_name='repo_creating', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_creating.mako') + attr="repo_creating", + route_name="repo_creating", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_creating.mako", + ) - config.add_route( - name='repo_creating_check', - pattern='/{repo_name:.*?[^/]}/repo_creating_check') + config.add_route(name="repo_creating_check", pattern="/{repo_name:.*?[^/]}/repo_creating_check") config.add_view( RepoChecksView, - attr='repo_creating_check', - route_name='repo_creating_check', request_method='GET', - renderer='json_ext') + attr="repo_creating_check", + route_name="repo_creating_check", + request_method="GET", + renderer="json_ext", + ) # Summary # NOTE(marcink): one additional route is defined in very bottom, catch # all pattern - config.add_route( - name='repo_summary_explicit', - pattern='/{repo_name:.*?[^/]}/summary', repo_route=True) + config.add_route(name="repo_summary_explicit", pattern="/{repo_name:.*?[^/]}/summary", repo_route=True) config.add_view( RepoSummaryView, - attr='summary', - route_name='repo_summary_explicit', request_method='GET', - renderer='rhodecode:templates/summary/summary.mako') + attr="summary", + route_name="repo_summary_explicit", + request_method="GET", + renderer="rhodecode:templates/summary/summary.mako", + ) - config.add_route( - name='repo_summary_commits', - pattern='/{repo_name:.*?[^/]}/summary-commits', repo_route=True) + config.add_route(name="repo_summary_commits", pattern="/{repo_name:.*?[^/]}/summary-commits", repo_route=True) config.add_view( RepoSummaryView, - attr='summary_commits', - route_name='repo_summary_commits', request_method='GET', - renderer='rhodecode:templates/summary/summary_commits.mako') - + attr="summary_commits", + route_name="repo_summary_commits", + request_method="GET", + renderer="rhodecode:templates/summary/summary_commits.mako", + ) + # Commits - config.add_route( - name='repo_commit', - pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}', repo_route=True) + config.add_route(name="repo_commit", pattern="/{repo_name:.*?[^/]}/changeset/{commit_id}", repo_route=True) config.add_view( - RepoCommitsView, - attr='repo_commit_show', - route_name='repo_commit', request_method='GET', - renderer=None) + RepoCommitsView, attr="repo_commit_show", route_name="repo_commit", request_method="GET", renderer=None + ) config.add_route( - name='repo_commit_children', - pattern='/{repo_name:.*?[^/]}/changeset_children/{commit_id}', repo_route=True) + name="repo_commit_children", pattern="/{repo_name:.*?[^/]}/changeset_children/{commit_id}", repo_route=True + ) config.add_view( RepoCommitsView, - attr='repo_commit_children', - route_name='repo_commit_children', request_method='GET', - renderer='json_ext', xhr=True) + attr="repo_commit_children", + route_name="repo_commit_children", + request_method="GET", + renderer="json_ext", + xhr=True, + ) config.add_route( - name='repo_commit_parents', - pattern='/{repo_name:.*?[^/]}/changeset_parents/{commit_id}', repo_route=True) + name="repo_commit_parents", pattern="/{repo_name:.*?[^/]}/changeset_parents/{commit_id}", repo_route=True + ) config.add_view( RepoCommitsView, - attr='repo_commit_parents', - route_name='repo_commit_parents', request_method='GET', - renderer='json_ext') + attr="repo_commit_parents", + route_name="repo_commit_parents", + request_method="GET", + renderer="json_ext", + ) + + config.add_route(name="repo_commit_raw", pattern="/{repo_name:.*?[^/]}/changeset-diff/{commit_id}", repo_route=True) + config.add_view( + RepoCommitsView, attr="repo_commit_raw", route_name="repo_commit_raw", request_method="GET", renderer=None + ) config.add_route( - name='repo_commit_raw', - pattern='/{repo_name:.*?[^/]}/changeset-diff/{commit_id}', repo_route=True) + name="repo_commit_patch", pattern="/{repo_name:.*?[^/]}/changeset-patch/{commit_id}", repo_route=True + ) config.add_view( - RepoCommitsView, - attr='repo_commit_raw', - route_name='repo_commit_raw', request_method='GET', - renderer=None) + RepoCommitsView, attr="repo_commit_patch", route_name="repo_commit_patch", request_method="GET", renderer=None + ) config.add_route( - name='repo_commit_patch', - pattern='/{repo_name:.*?[^/]}/changeset-patch/{commit_id}', repo_route=True) + name="repo_commit_download", pattern="/{repo_name:.*?[^/]}/changeset-download/{commit_id}", repo_route=True + ) config.add_view( RepoCommitsView, - attr='repo_commit_patch', - route_name='repo_commit_patch', request_method='GET', - renderer=None) + attr="repo_commit_download", + route_name="repo_commit_download", + request_method="GET", + renderer=None, + ) config.add_route( - name='repo_commit_download', - pattern='/{repo_name:.*?[^/]}/changeset-download/{commit_id}', repo_route=True) + name="repo_commit_data", pattern="/{repo_name:.*?[^/]}/changeset-data/{commit_id}", repo_route=True + ) config.add_view( RepoCommitsView, - attr='repo_commit_download', - route_name='repo_commit_download', request_method='GET', - renderer=None) + attr="repo_commit_data", + route_name="repo_commit_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) config.add_route( - name='repo_commit_data', - pattern='/{repo_name:.*?[^/]}/changeset-data/{commit_id}', repo_route=True) + name="repo_commit_comment_create", + pattern="/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/create", + repo_route=True, + ) config.add_view( RepoCommitsView, - attr='repo_commit_data', - route_name='repo_commit_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="repo_commit_comment_create", + route_name="repo_commit_comment_create", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='repo_commit_comment_create', - pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/create', repo_route=True) + name="repo_commit_comment_preview", + pattern="/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/preview", + repo_route=True, + ) config.add_view( RepoCommitsView, - attr='repo_commit_comment_create', - route_name='repo_commit_comment_create', request_method='POST', - renderer='json_ext') + attr="repo_commit_comment_preview", + route_name="repo_commit_comment_preview", + request_method="POST", + renderer="string", + xhr=True, + ) config.add_route( - name='repo_commit_comment_preview', - pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/preview', repo_route=True) + name="repo_commit_comment_history_view", + pattern="/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/{comment_id}/history_view/{comment_history_id}", + repo_route=True, + ) config.add_view( RepoCommitsView, - attr='repo_commit_comment_preview', - route_name='repo_commit_comment_preview', request_method='POST', - renderer='string', xhr=True) + attr="repo_commit_comment_history_view", + route_name="repo_commit_comment_history_view", + request_method="POST", + renderer="string", + xhr=True, + ) config.add_route( - name='repo_commit_comment_history_view', - pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/{comment_id}/history_view/{comment_history_id}', repo_route=True) + name="repo_commit_comment_attachment_upload", + pattern="/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/attachment_upload", + repo_route=True, + ) config.add_view( RepoCommitsView, - attr='repo_commit_comment_history_view', - route_name='repo_commit_comment_history_view', request_method='POST', - renderer='string', xhr=True) + attr="repo_commit_comment_attachment_upload", + route_name="repo_commit_comment_attachment_upload", + request_method="POST", + renderer="json_ext", + xhr=True, + ) config.add_route( - name='repo_commit_comment_attachment_upload', - pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/attachment_upload', repo_route=True) + name="repo_commit_comment_delete", + pattern="/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/{comment_id}/delete", + repo_route=True, + ) config.add_view( RepoCommitsView, - attr='repo_commit_comment_attachment_upload', - route_name='repo_commit_comment_attachment_upload', request_method='POST', - renderer='json_ext', xhr=True) + attr="repo_commit_comment_delete", + route_name="repo_commit_comment_delete", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='repo_commit_comment_delete', - pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/{comment_id}/delete', repo_route=True) + name="repo_commit_comment_edit", + pattern="/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/{comment_id}/edit", + repo_route=True, + ) config.add_view( RepoCommitsView, - attr='repo_commit_comment_delete', - route_name='repo_commit_comment_delete', request_method='POST', - renderer='json_ext') - - config.add_route( - name='repo_commit_comment_edit', - pattern='/{repo_name:.*?[^/]}/changeset/{commit_id}/comment/{comment_id}/edit', repo_route=True) - config.add_view( - RepoCommitsView, - attr='repo_commit_comment_edit', - route_name='repo_commit_comment_edit', request_method='POST', - renderer='json_ext') + attr="repo_commit_comment_edit", + route_name="repo_commit_comment_edit", + request_method="POST", + renderer="json_ext", + ) # still working url for backward compat. config.add_route( - name='repo_commit_raw_deprecated', - pattern='/{repo_name:.*?[^/]}/raw-changeset/{commit_id}', repo_route=True) + name="repo_commit_raw_deprecated", pattern="/{repo_name:.*?[^/]}/raw-changeset/{commit_id}", repo_route=True + ) config.add_view( RepoCommitsView, - attr='repo_commit_raw', - route_name='repo_commit_raw_deprecated', request_method='GET', - renderer=None) - - # Files - config.add_route( - name='repo_archivefile', - pattern='/{repo_name:.*?[^/]}/archive/{fname:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_archivefile', - route_name='repo_archivefile', request_method='GET', - renderer=None) - - config.add_route( - name='repo_files_diff', - pattern='/{repo_name:.*?[^/]}/diff/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_diff', - route_name='repo_files_diff', request_method='GET', - renderer=None) - - config.add_route( # legacy route to make old links work - name='repo_files_diff_2way_redirect', - pattern='/{repo_name:.*?[^/]}/diff-2way/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_diff_2way_redirect', - route_name='repo_files_diff_2way_redirect', request_method='GET', - renderer=None) - - config.add_route( - name='repo_files', - pattern='/{repo_name:.*?[^/]}/files/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files', - route_name='repo_files', request_method='GET', - renderer=None) - - config.add_route( - name='repo_files:default_path', - pattern='/{repo_name:.*?[^/]}/files/{commit_id}/', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files', - route_name='repo_files:default_path', request_method='GET', - renderer=None) - - config.add_route( - name='repo_files:default_commit', - pattern='/{repo_name:.*?[^/]}/files', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files', - route_name='repo_files:default_commit', request_method='GET', - renderer=None) - - config.add_route( - name='repo_files:rendered', - pattern='/{repo_name:.*?[^/]}/render/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files', - route_name='repo_files:rendered', request_method='GET', - renderer=None) - - config.add_route( - name='repo_files:annotated', - pattern='/{repo_name:.*?[^/]}/annotate/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files', - route_name='repo_files:annotated', request_method='GET', - renderer=None) - - config.add_route( - name='repo_files:annotated_previous', - pattern='/{repo_name:.*?[^/]}/annotate-previous/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_annotated_previous', - route_name='repo_files:annotated_previous', request_method='GET', - renderer=None) - - config.add_route( - name='repo_nodetree_full', - pattern='/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_nodetree_full', - route_name='repo_nodetree_full', request_method='GET', - renderer=None, xhr=True) - - config.add_route( - name='repo_nodetree_full:default_path', - pattern='/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_nodetree_full', - route_name='repo_nodetree_full:default_path', request_method='GET', - renderer=None, xhr=True) - - config.add_route( - name='repo_files_nodelist', - pattern='/{repo_name:.*?[^/]}/nodelist/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_nodelist', - route_name='repo_files_nodelist', request_method='GET', - renderer='json_ext', xhr=True) - - config.add_route( - name='repo_file_raw', - pattern='/{repo_name:.*?[^/]}/raw/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_file_raw', - route_name='repo_file_raw', request_method='GET', - renderer=None) - - config.add_route( - name='repo_file_download', - pattern='/{repo_name:.*?[^/]}/download/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_file_download', - route_name='repo_file_download', request_method='GET', - renderer=None) - - config.add_route( # backward compat to keep old links working - name='repo_file_download:legacy', - pattern='/{repo_name:.*?[^/]}/rawfile/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_file_download', - route_name='repo_file_download:legacy', request_method='GET', - renderer=None) - - config.add_route( - name='repo_file_history', - pattern='/{repo_name:.*?[^/]}/history/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_file_history', - route_name='repo_file_history', request_method='GET', - renderer='json_ext') - - config.add_route( - name='repo_file_authors', - pattern='/{repo_name:.*?[^/]}/authors/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_file_authors', - route_name='repo_file_authors', request_method='GET', - renderer='rhodecode:templates/files/file_authors_box.mako') - - config.add_route( - name='repo_files_check_head', - pattern='/{repo_name:.*?[^/]}/check_head/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_check_head', - route_name='repo_files_check_head', request_method='POST', - renderer='json_ext', xhr=True) - - config.add_route( - name='repo_files_remove_file', - pattern='/{repo_name:.*?[^/]}/remove_file/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_remove_file', - route_name='repo_files_remove_file', request_method='GET', - renderer='rhodecode:templates/files/files_delete.mako') - - config.add_route( - name='repo_files_delete_file', - pattern='/{repo_name:.*?[^/]}/delete_file/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_delete_file', - route_name='repo_files_delete_file', request_method='POST', - renderer=None) - - config.add_route( - name='repo_files_edit_file', - pattern='/{repo_name:.*?[^/]}/edit_file/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_edit_file', - route_name='repo_files_edit_file', request_method='GET', - renderer='rhodecode:templates/files/files_edit.mako') - - config.add_route( - name='repo_files_update_file', - pattern='/{repo_name:.*?[^/]}/update_file/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_update_file', - route_name='repo_files_update_file', request_method='POST', - renderer=None) - - config.add_route( - name='repo_files_add_file', - pattern='/{repo_name:.*?[^/]}/add_file/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_add_file', - route_name='repo_files_add_file', request_method='GET', - renderer='rhodecode:templates/files/files_add.mako') - - config.add_route( - name='repo_files_upload_file', - pattern='/{repo_name:.*?[^/]}/upload_file/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_add_file', - route_name='repo_files_upload_file', request_method='GET', - renderer='rhodecode:templates/files/files_upload.mako') - config.add_view( # POST creates - RepoFilesView, - attr='repo_files_upload_file', - route_name='repo_files_upload_file', request_method='POST', - renderer='json_ext') - - config.add_route( - name='repo_files_replace_binary', - pattern='/{repo_name:.*?[^/]}/replace_binary/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( - RepoFilesView, - attr='repo_files_replace_file', - route_name='repo_files_replace_binary', request_method='POST', - renderer='json_ext') - - config.add_route( - name='repo_files_create_file', - pattern='/{repo_name:.*?[^/]}/create_file/{commit_id}/{f_path:.*}', - repo_route=True) - config.add_view( # POST creates - RepoFilesView, - attr='repo_files_create_file', - route_name='repo_files_create_file', request_method='POST', - renderer=None) - - # Refs data - config.add_route( - name='repo_refs_data', - pattern='/{repo_name:.*?[^/]}/refs-data', repo_route=True) - config.add_view( - RepoSummaryView, - attr='repo_refs_data', - route_name='repo_refs_data', request_method='GET', - renderer='json_ext') - - config.add_route( - name='repo_refs_changelog_data', - pattern='/{repo_name:.*?[^/]}/refs-data-changelog', repo_route=True) - config.add_view( - RepoSummaryView, - attr='repo_refs_changelog_data', - route_name='repo_refs_changelog_data', request_method='GET', - renderer='json_ext') - - config.add_route( - name='repo_stats', - pattern='/{repo_name:.*?[^/]}/repo_stats/{commit_id}', repo_route=True) - config.add_view( - RepoSummaryView, - attr='repo_stats', - route_name='repo_stats', request_method='GET', - renderer='json_ext') - - # Commits - config.add_route( - name='repo_commits', - pattern='/{repo_name:.*?[^/]}/commits', repo_route=True) - config.add_view( - RepoChangelogView, - attr='repo_changelog', - route_name='repo_commits', request_method='GET', - renderer='rhodecode:templates/commits/changelog.mako') - # old routes for backward compat - config.add_view( - RepoChangelogView, - attr='repo_changelog', - route_name='repo_changelog', request_method='GET', - renderer='rhodecode:templates/commits/changelog.mako') - - config.add_route( - name='repo_commits_elements', - pattern='/{repo_name:.*?[^/]}/commits_elements', repo_route=True) - config.add_view( - RepoChangelogView, - attr='repo_commits_elements', - route_name='repo_commits_elements', request_method=('GET', 'POST'), - renderer='rhodecode:templates/commits/changelog_elements.mako', - xhr=True) - - config.add_route( - name='repo_commits_elements_file', - pattern='/{repo_name:.*?[^/]}/commits_elements/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoChangelogView, - attr='repo_commits_elements', - route_name='repo_commits_elements_file', request_method=('GET', 'POST'), - renderer='rhodecode:templates/commits/changelog_elements.mako', - xhr=True) - - config.add_route( - name='repo_commits_file', - pattern='/{repo_name:.*?[^/]}/commits/{commit_id}/{f_path:.*}', repo_route=True) - config.add_view( - RepoChangelogView, - attr='repo_changelog', - route_name='repo_commits_file', request_method='GET', - renderer='rhodecode:templates/commits/changelog.mako') - # old routes for backward compat - config.add_view( - RepoChangelogView, - attr='repo_changelog', - route_name='repo_changelog_file', request_method='GET', - renderer='rhodecode:templates/commits/changelog.mako') - - # Changelog (old deprecated name for commits page) - config.add_route( - name='repo_changelog', - pattern='/{repo_name:.*?[^/]}/changelog', repo_route=True) - config.add_route( - name='repo_changelog_file', - pattern='/{repo_name:.*?[^/]}/changelog/{commit_id}/{f_path:.*}', repo_route=True) - - # Compare - config.add_route( - name='repo_compare_select', - pattern='/{repo_name:.*?[^/]}/compare', repo_route=True) - config.add_view( - RepoCompareView, - attr='compare_select', - route_name='repo_compare_select', request_method='GET', - renderer='rhodecode:templates/compare/compare_diff.mako') - - config.add_route( - name='repo_compare', - pattern='/{repo_name:.*?[^/]}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}', repo_route=True) - config.add_view( - RepoCompareView, - attr='compare', - route_name='repo_compare', request_method='GET', - renderer=None) - - # Tags - config.add_route( - name='tags_home', - pattern='/{repo_name:.*?[^/]}/tags', repo_route=True) - config.add_view( - RepoTagsView, - attr='tags', - route_name='tags_home', request_method='GET', - renderer='rhodecode:templates/tags/tags.mako') - - # Branches - config.add_route( - name='branches_home', - pattern='/{repo_name:.*?[^/]}/branches', repo_route=True) - config.add_view( - RepoBranchesView, - attr='branches', - route_name='branches_home', request_method='GET', - renderer='rhodecode:templates/branches/branches.mako') - - config.add_route( - name='branch_remove', - pattern='/{repo_name:.*?[^/]}/branches/{branch_name:.*?[^/]}/remove', repo_route=True, repo_accepted_types=['hg', 'git']) - config.add_view( - RepoBranchesView, - attr='remove_branch', - route_name='branch_remove', request_method='POST' + attr="repo_commit_raw", + route_name="repo_commit_raw_deprecated", + request_method="GET", + renderer=None, + ) + + # Files + config.add_route(name="repo_archivefile", pattern="/{repo_name:.*?[^/]}/archive/{fname:.*}", repo_route=True) + config.add_view( + RepoFilesView, attr="repo_archivefile", route_name="repo_archivefile", request_method="GET", renderer=None + ) + + config.add_route(name="repo_files_diff", pattern="/{repo_name:.*?[^/]}/diff/{f_path:.*}", repo_route=True) + config.add_view( + RepoFilesView, attr="repo_files_diff", route_name="repo_files_diff", request_method="GET", renderer=None + ) + + config.add_route( # legacy route to make old links work + name="repo_files_diff_2way_redirect", pattern="/{repo_name:.*?[^/]}/diff-2way/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_files_diff_2way_redirect", + route_name="repo_files_diff_2way_redirect", + request_method="GET", + renderer=None, + ) + + config.add_route(name="repo_files", pattern="/{repo_name:.*?[^/]}/files/{commit_id}/{f_path:.*}", repo_route=True) + config.add_view(RepoFilesView, attr="repo_files", route_name="repo_files", request_method="GET", renderer=None) + + config.add_route(name="repo_files:default_path", pattern="/{repo_name:.*?[^/]}/files/{commit_id}/", repo_route=True) + config.add_view( + RepoFilesView, attr="repo_files", route_name="repo_files:default_path", request_method="GET", renderer=None + ) + + config.add_route(name="repo_files:default_commit", pattern="/{repo_name:.*?[^/]}/files", repo_route=True) + config.add_view( + RepoFilesView, attr="repo_files", route_name="repo_files:default_commit", request_method="GET", renderer=None ) - # Bookmarks config.add_route( - name='bookmarks_home', - pattern='/{repo_name:.*?[^/]}/bookmarks', repo_route=True) + name="repo_files:rendered", pattern="/{repo_name:.*?[^/]}/render/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, attr="repo_files", route_name="repo_files:rendered", request_method="GET", renderer=None + ) + + config.add_route( + name="repo_files:annotated", pattern="/{repo_name:.*?[^/]}/annotate/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, attr="repo_files", route_name="repo_files:annotated", request_method="GET", renderer=None + ) + + config.add_route( + name="repo_files:annotated_previous", + pattern="/{repo_name:.*?[^/]}/annotate-previous/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_files_annotated_previous", + route_name="repo_files:annotated_previous", + request_method="GET", + renderer=None, + ) + + config.add_route( + name="repo_nodetree_full", pattern="/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_nodetree_full", + route_name="repo_nodetree_full", + request_method="GET", + renderer=None, + xhr=True, + ) + + config.add_route( + name="repo_nodetree_full:default_path", + pattern="/{repo_name:.*?[^/]}/nodetree_full/{commit_id}/", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_nodetree_full", + route_name="repo_nodetree_full:default_path", + request_method="GET", + renderer=None, + xhr=True, + ) + + config.add_route( + name="repo_files_nodelist", pattern="/{repo_name:.*?[^/]}/nodelist/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_nodelist", + route_name="repo_files_nodelist", + request_method="GET", + renderer="json_ext", + xhr=True, + ) + + config.add_route(name="repo_file_raw", pattern="/{repo_name:.*?[^/]}/raw/{commit_id}/{f_path:.*}", repo_route=True) + config.add_view( + RepoFilesView, attr="repo_file_raw", route_name="repo_file_raw", request_method="GET", renderer=None + ) + + config.add_route( + name="repo_file_download", pattern="/{repo_name:.*?[^/]}/download/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, attr="repo_file_download", route_name="repo_file_download", request_method="GET", renderer=None + ) + + config.add_route( # backward compat to keep old links working + name="repo_file_download:legacy", + pattern="/{repo_name:.*?[^/]}/rawfile/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_file_download", + route_name="repo_file_download:legacy", + request_method="GET", + renderer=None, + ) + + config.add_route( + name="repo_file_history", pattern="/{repo_name:.*?[^/]}/history/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_file_history", + route_name="repo_file_history", + request_method="GET", + renderer="json_ext", + ) + + config.add_route( + name="repo_file_authors", pattern="/{repo_name:.*?[^/]}/authors/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_file_authors", + route_name="repo_file_authors", + request_method="GET", + renderer="rhodecode:templates/files/file_authors_box.mako", + ) + + config.add_route( + name="repo_files_check_head", pattern="/{repo_name:.*?[^/]}/check_head/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_files_check_head", + route_name="repo_files_check_head", + request_method="POST", + renderer="json_ext", + xhr=True, + ) + + config.add_route( + name="repo_files_remove_file", + pattern="/{repo_name:.*?[^/]}/remove_file/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_files_remove_file", + route_name="repo_files_remove_file", + request_method="GET", + renderer="rhodecode:templates/files/files_delete.mako", + ) + + config.add_route( + name="repo_files_delete_file", + pattern="/{repo_name:.*?[^/]}/delete_file/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_files_delete_file", + route_name="repo_files_delete_file", + request_method="POST", + renderer=None, + ) + + config.add_route( + name="repo_files_edit_file", pattern="/{repo_name:.*?[^/]}/edit_file/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_files_edit_file", + route_name="repo_files_edit_file", + request_method="GET", + renderer="rhodecode:templates/files/files_edit.mako", + ) + + config.add_route( + name="repo_files_update_file", + pattern="/{repo_name:.*?[^/]}/update_file/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_files_update_file", + route_name="repo_files_update_file", + request_method="POST", + renderer=None, + ) + + config.add_route( + name="repo_files_add_file", pattern="/{repo_name:.*?[^/]}/add_file/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoFilesView, + attr="repo_files_add_file", + route_name="repo_files_add_file", + request_method="GET", + renderer="rhodecode:templates/files/files_add.mako", + ) + + config.add_route( + name="repo_files_upload_file", + pattern="/{repo_name:.*?[^/]}/upload_file/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_files_add_file", + route_name="repo_files_upload_file", + request_method="GET", + renderer="rhodecode:templates/files/files_upload.mako", + ) + config.add_view( # POST creates + RepoFilesView, + attr="repo_files_upload_file", + route_name="repo_files_upload_file", + request_method="POST", + renderer="json_ext", + ) + + config.add_route( + name="repo_files_replace_binary", + pattern="/{repo_name:.*?[^/]}/replace_binary/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoFilesView, + attr="repo_files_replace_file", + route_name="repo_files_replace_binary", + request_method="POST", + renderer="json_ext", + ) + + config.add_route( + name="repo_files_create_file", + pattern="/{repo_name:.*?[^/]}/create_file/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( # POST creates + RepoFilesView, + attr="repo_files_create_file", + route_name="repo_files_create_file", + request_method="POST", + renderer=None, + ) + + # Refs data + config.add_route(name="repo_refs_data", pattern="/{repo_name:.*?[^/]}/refs-data", repo_route=True) + config.add_view( + RepoSummaryView, attr="repo_refs_data", route_name="repo_refs_data", request_method="GET", renderer="json_ext" + ) + + config.add_route( + name="repo_refs_changelog_data", pattern="/{repo_name:.*?[^/]}/refs-data-changelog", repo_route=True + ) + config.add_view( + RepoSummaryView, + attr="repo_refs_changelog_data", + route_name="repo_refs_changelog_data", + request_method="GET", + renderer="json_ext", + ) + + config.add_route(name="repo_stats", pattern="/{repo_name:.*?[^/]}/repo_stats/{commit_id}", repo_route=True) + config.add_view( + RepoSummaryView, attr="repo_stats", route_name="repo_stats", request_method="GET", renderer="json_ext" + ) + + # Commits + config.add_route(name="repo_commits", pattern="/{repo_name:.*?[^/]}/commits", repo_route=True) + config.add_view( + RepoChangelogView, + attr="repo_changelog", + route_name="repo_commits", + request_method="GET", + renderer="rhodecode:templates/commits/changelog.mako", + ) + # old routes for backward compat + config.add_view( + RepoChangelogView, + attr="repo_changelog", + route_name="repo_changelog", + request_method="GET", + renderer="rhodecode:templates/commits/changelog.mako", + ) + + config.add_route(name="repo_commits_elements", pattern="/{repo_name:.*?[^/]}/commits_elements", repo_route=True) + config.add_view( + RepoChangelogView, + attr="repo_commits_elements", + route_name="repo_commits_elements", + request_method=("GET", "POST"), + renderer="rhodecode:templates/commits/changelog_elements.mako", + xhr=True, + ) + + config.add_route( + name="repo_commits_elements_file", + pattern="/{repo_name:.*?[^/]}/commits_elements/{commit_id}/{f_path:.*}", + repo_route=True, + ) + config.add_view( + RepoChangelogView, + attr="repo_commits_elements", + route_name="repo_commits_elements_file", + request_method=("GET", "POST"), + renderer="rhodecode:templates/commits/changelog_elements.mako", + xhr=True, + ) + + config.add_route( + name="repo_commits_file", pattern="/{repo_name:.*?[^/]}/commits/{commit_id}/{f_path:.*}", repo_route=True + ) + config.add_view( + RepoChangelogView, + attr="repo_changelog", + route_name="repo_commits_file", + request_method="GET", + renderer="rhodecode:templates/commits/changelog.mako", + ) + # old routes for backward compat + config.add_view( + RepoChangelogView, + attr="repo_changelog", + route_name="repo_changelog_file", + request_method="GET", + renderer="rhodecode:templates/commits/changelog.mako", + ) + + # Changelog (old deprecated name for commits page) + config.add_route(name="repo_changelog", pattern="/{repo_name:.*?[^/]}/changelog", repo_route=True) + config.add_route( + name="repo_changelog_file", pattern="/{repo_name:.*?[^/]}/changelog/{commit_id}/{f_path:.*}", repo_route=True + ) + + # Compare + config.add_route(name="repo_compare_select", pattern="/{repo_name:.*?[^/]}/compare", repo_route=True) + config.add_view( + RepoCompareView, + attr="compare_select", + route_name="repo_compare_select", + request_method="GET", + renderer="rhodecode:templates/compare/compare_diff.mako", + ) + + config.add_route( + name="repo_compare", + pattern="/{repo_name:.*?[^/]}/compare/{source_ref_type}@{source_ref:.*?}...{target_ref_type}@{target_ref:.*?}", + repo_route=True, + ) + config.add_view(RepoCompareView, attr="compare", route_name="repo_compare", request_method="GET", renderer=None) + + # Tags + config.add_route(name="tags_home", pattern="/{repo_name:.*?[^/]}/tags", repo_route=True) + config.add_view( + RepoTagsView, + attr="tags", + route_name="tags_home", + request_method="GET", + renderer="rhodecode:templates/tags/tags.mako", + ) + + # Branches + config.add_route(name="branches_home", pattern="/{repo_name:.*?[^/]}/branches", repo_route=True) + config.add_view( + RepoBranchesView, + attr="branches", + route_name="branches_home", + request_method="GET", + renderer="rhodecode:templates/branches/branches.mako", + ) + + config.add_route( + name="branch_remove", + pattern="/{repo_name:.*?[^/]}/branches/{branch_name:.*?[^/]}/remove", + repo_route=True, + repo_accepted_types=["hg", "git"], + ) + config.add_view(RepoBranchesView, attr="remove_branch", route_name="branch_remove", request_method="POST") + + # Bookmarks + config.add_route(name="bookmarks_home", pattern="/{repo_name:.*?[^/]}/bookmarks", repo_route=True) config.add_view( RepoBookmarksView, - attr='bookmarks', - route_name='bookmarks_home', request_method='GET', - renderer='rhodecode:templates/bookmarks/bookmarks.mako') + attr="bookmarks", + route_name="bookmarks_home", + request_method="GET", + renderer="rhodecode:templates/bookmarks/bookmarks.mako", + ) # Forks config.add_route( - name='repo_fork_new', - pattern='/{repo_name:.*?[^/]}/fork', repo_route=True, + name="repo_fork_new", + pattern="/{repo_name:.*?[^/]}/fork", + repo_route=True, repo_forbid_when_archived=True, - repo_accepted_types=['hg', 'git']) + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoForksView, - attr='repo_fork_new', - route_name='repo_fork_new', request_method='GET', - renderer='rhodecode:templates/forks/forks.mako') + attr="repo_fork_new", + route_name="repo_fork_new", + request_method="GET", + renderer="rhodecode:templates/forks/forks.mako", + ) config.add_route( - name='repo_fork_create', - pattern='/{repo_name:.*?[^/]}/fork/create', repo_route=True, + name="repo_fork_create", + pattern="/{repo_name:.*?[^/]}/fork/create", + repo_route=True, repo_forbid_when_archived=True, - repo_accepted_types=['hg', 'git']) + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoForksView, - attr='repo_fork_create', - route_name='repo_fork_create', request_method='POST', - renderer='rhodecode:templates/forks/fork.mako') + attr="repo_fork_create", + route_name="repo_fork_create", + request_method="POST", + renderer="rhodecode:templates/forks/fork.mako", + ) config.add_route( - name='repo_forks_show_all', - pattern='/{repo_name:.*?[^/]}/forks', repo_route=True, - repo_accepted_types=['hg', 'git']) + name="repo_forks_show_all", + pattern="/{repo_name:.*?[^/]}/forks", + repo_route=True, + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoForksView, - attr='repo_forks_show_all', - route_name='repo_forks_show_all', request_method='GET', - renderer='rhodecode:templates/forks/forks.mako') - + attr="repo_forks_show_all", + route_name="repo_forks_show_all", + request_method="GET", + renderer="rhodecode:templates/forks/forks.mako", + ) + config.add_route( - name='repo_forks_data', - pattern='/{repo_name:.*?[^/]}/forks/data', repo_route=True, - repo_accepted_types=['hg', 'git']) + name="repo_forks_data", + pattern="/{repo_name:.*?[^/]}/forks/data", + repo_route=True, + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoForksView, - attr='repo_forks_data', - route_name='repo_forks_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="repo_forks_data", + route_name="repo_forks_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) # Pull Requests config.add_route( - name='pullrequest_show', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}', - repo_route=True) + name="pullrequest_show", pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}", repo_route=True + ) config.add_view( RepoPullRequestsView, - attr='pull_request_show', - route_name='pullrequest_show', request_method='GET', - renderer='rhodecode:templates/pullrequests/pullrequest_show.mako') + attr="pull_request_show", + route_name="pullrequest_show", + request_method="GET", + renderer="rhodecode:templates/pullrequests/pullrequest_show.mako", + ) config.add_route( - name='pullrequest_show_all', - pattern='/{repo_name:.*?[^/]}/pull-request', - repo_route=True, repo_accepted_types=['hg', 'git']) + name="pullrequest_show_all", + pattern="/{repo_name:.*?[^/]}/pull-request", + repo_route=True, + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoPullRequestsView, - attr='pull_request_list', - route_name='pullrequest_show_all', request_method='GET', - renderer='rhodecode:templates/pullrequests/pullrequests.mako') + attr="pull_request_list", + route_name="pullrequest_show_all", + request_method="GET", + renderer="rhodecode:templates/pullrequests/pullrequests.mako", + ) config.add_route( - name='pullrequest_show_all_data', - pattern='/{repo_name:.*?[^/]}/pull-request-data', - repo_route=True, repo_accepted_types=['hg', 'git']) + name="pullrequest_show_all_data", + pattern="/{repo_name:.*?[^/]}/pull-request-data", + repo_route=True, + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoPullRequestsView, - attr='pull_request_list_data', - route_name='pullrequest_show_all_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="pull_request_list_data", + route_name="pullrequest_show_all_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) config.add_route( - name='pullrequest_repo_refs', - pattern='/{repo_name:.*?[^/]}/pull-request/refs/{target_repo_name:.*?[^/]}', - repo_route=True) + name="pullrequest_repo_refs", + pattern="/{repo_name:.*?[^/]}/pull-request/refs/{target_repo_name:.*?[^/]}", + repo_route=True, + ) config.add_view( RepoPullRequestsView, - attr='pull_request_repo_refs', - route_name='pullrequest_repo_refs', request_method='GET', - renderer='json_ext', xhr=True) + attr="pull_request_repo_refs", + route_name="pullrequest_repo_refs", + request_method="GET", + renderer="json_ext", + xhr=True, + ) config.add_route( - name='pullrequest_repo_targets', - pattern='/{repo_name:.*?[^/]}/pull-request/repo-targets', - repo_route=True) + name="pullrequest_repo_targets", pattern="/{repo_name:.*?[^/]}/pull-request/repo-targets", repo_route=True + ) config.add_view( RepoPullRequestsView, - attr='pullrequest_repo_targets', - route_name='pullrequest_repo_targets', request_method='GET', - renderer='json_ext', xhr=True) + attr="pullrequest_repo_targets", + route_name="pullrequest_repo_targets", + request_method="GET", + renderer="json_ext", + xhr=True, + ) config.add_route( - name='pullrequest_new', - pattern='/{repo_name:.*?[^/]}/pull-request/new', - repo_route=True, repo_accepted_types=['hg', 'git'], - repo_forbid_when_archived=True) + name="pullrequest_new", + pattern="/{repo_name:.*?[^/]}/pull-request/new", + repo_route=True, + repo_accepted_types=["hg", "git"], + repo_forbid_when_archived=True, + ) config.add_view( RepoPullRequestsView, - attr='pull_request_new', - route_name='pullrequest_new', request_method='GET', - renderer='rhodecode:templates/pullrequests/pullrequest.mako') + attr="pull_request_new", + route_name="pullrequest_new", + request_method="GET", + renderer="rhodecode:templates/pullrequests/pullrequest.mako", + ) config.add_route( - name='pullrequest_create', - pattern='/{repo_name:.*?[^/]}/pull-request/create', - repo_route=True, repo_accepted_types=['hg', 'git'], - repo_forbid_when_archived=True) + name="pullrequest_create", + pattern="/{repo_name:.*?[^/]}/pull-request/create", + repo_route=True, + repo_accepted_types=["hg", "git"], + repo_forbid_when_archived=True, + ) config.add_view( RepoPullRequestsView, - attr='pull_request_create', - route_name='pullrequest_create', request_method='POST', - renderer=None) + attr="pull_request_create", + route_name="pullrequest_create", + request_method="POST", + renderer=None, + ) config.add_route( - name='pullrequest_update', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/update', - repo_route=True, repo_forbid_when_archived=True) + name="pullrequest_update", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/update", + repo_route=True, + repo_forbid_when_archived=True, + ) config.add_view( RepoPullRequestsView, - attr='pull_request_update', - route_name='pullrequest_update', request_method='POST', - renderer='json_ext') + attr="pull_request_update", + route_name="pullrequest_update", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='pullrequest_merge', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/merge', - repo_route=True, repo_forbid_when_archived=True) + name="pullrequest_merge", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/merge", + repo_route=True, + repo_forbid_when_archived=True, + ) config.add_view( RepoPullRequestsView, - attr='pull_request_merge', - route_name='pullrequest_merge', request_method='POST', - renderer='json_ext') + attr="pull_request_merge", + route_name="pullrequest_merge", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='pullrequest_delete', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/delete', - repo_route=True, repo_forbid_when_archived=True) + name="pullrequest_delete", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/delete", + repo_route=True, + repo_forbid_when_archived=True, + ) config.add_view( RepoPullRequestsView, - attr='pull_request_delete', - route_name='pullrequest_delete', request_method='POST', - renderer='json_ext') + attr="pull_request_delete", + route_name="pullrequest_delete", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='pullrequest_comment_create', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment', - repo_route=True) + name="pullrequest_comment_create", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment", + repo_route=True, + ) config.add_view( RepoPullRequestsView, - attr='pull_request_comment_create', - route_name='pullrequest_comment_create', request_method='POST', - renderer='json_ext') + attr="pull_request_comment_create", + route_name="pullrequest_comment_create", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='pullrequest_comment_edit', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/edit', - repo_route=True, repo_accepted_types=['hg', 'git']) + name="pullrequest_comment_edit", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/edit", + repo_route=True, + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoPullRequestsView, - attr='pull_request_comment_edit', - route_name='pullrequest_comment_edit', request_method='POST', - renderer='json_ext') + attr="pull_request_comment_edit", + route_name="pullrequest_comment_edit", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='pullrequest_comment_delete', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/delete', - repo_route=True, repo_accepted_types=['hg', 'git']) + name="pullrequest_comment_delete", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comment/{comment_id}/delete", + repo_route=True, + repo_accepted_types=["hg", "git"], + ) config.add_view( RepoPullRequestsView, - attr='pull_request_comment_delete', - route_name='pullrequest_comment_delete', request_method='POST', - renderer='json_ext') + attr="pull_request_comment_delete", + route_name="pullrequest_comment_delete", + request_method="POST", + renderer="json_ext", + ) config.add_route( - name='pullrequest_comments', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comments', - repo_route=True) + name="pullrequest_comments", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/comments", + repo_route=True, + ) config.add_view( RepoPullRequestsView, - attr='pullrequest_comments', - route_name='pullrequest_comments', request_method='POST', - renderer='string_html', xhr=True) + attr="pullrequest_comments", + route_name="pullrequest_comments", + request_method="POST", + renderer="string_html", + xhr=True, + ) config.add_route( - name='pullrequest_todos', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/todos', - repo_route=True) + name="pullrequest_todos", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/todos", + repo_route=True, + ) config.add_view( RepoPullRequestsView, - attr='pullrequest_todos', - route_name='pullrequest_todos', request_method='POST', - renderer='string_html', xhr=True) + attr="pullrequest_todos", + route_name="pullrequest_todos", + request_method="POST", + renderer="string_html", + xhr=True, + ) config.add_route( - name='pullrequest_drafts', - pattern=r'/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/drafts', - repo_route=True) + name="pullrequest_drafts", + pattern=r"/{repo_name:.*?[^/]}/pull-request/{pull_request_id:\d+}/drafts", + repo_route=True, + ) config.add_view( RepoPullRequestsView, - attr='pullrequest_drafts', - route_name='pullrequest_drafts', request_method='POST', - renderer='string_html', xhr=True) + attr="pullrequest_drafts", + route_name="pullrequest_drafts", + request_method="POST", + renderer="string_html", + xhr=True, + ) # Artifacts, (EE feature) - config.add_route( - name='repo_artifacts_list', - pattern='/{repo_name:.*?[^/]}/artifacts', repo_route=True) + config.add_route(name="repo_artifacts_list", pattern="/{repo_name:.*?[^/]}/artifacts", repo_route=True) config.add_view( RepoArtifactsView, - attr='repo_artifacts', - route_name='repo_artifacts_list', request_method='GET', - renderer='rhodecode:templates/artifacts/artifact_list.mako') + attr="repo_artifacts", + route_name="repo_artifacts_list", + request_method="GET", + renderer="rhodecode:templates/artifacts/artifact_list.mako", + ) # Settings - config.add_route( - name='edit_repo', - pattern='/{repo_name:.*?[^/]}/settings', repo_route=True) + config.add_route(name="edit_repo", pattern="/{repo_name:.*?[^/]}/settings", repo_route=True) config.add_view( RepoSettingsView, - attr='edit_settings', - route_name='edit_repo', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_settings", + route_name="edit_repo", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # update is POST on edit_repo config.add_view( RepoSettingsView, - attr='edit_settings_update', - route_name='edit_repo', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_settings_update", + route_name="edit_repo", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # Settings advanced - config.add_route( - name='edit_repo_advanced', - pattern='/{repo_name:.*?[^/]}/settings/advanced', repo_route=True) + config.add_route(name="edit_repo_advanced", pattern="/{repo_name:.*?[^/]}/settings/advanced", repo_route=True) config.add_view( RepoSettingsAdvancedView, - attr='edit_advanced', - route_name='edit_repo_advanced', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') - - config.add_route( - name='edit_repo_advanced_archive', - pattern='/{repo_name:.*?[^/]}/settings/advanced/archive', repo_route=True) - config.add_view( - RepoSettingsAdvancedView, - attr='edit_advanced_archive', - route_name='edit_repo_advanced_archive', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') - - config.add_route( - name='edit_repo_advanced_delete', - pattern='/{repo_name:.*?[^/]}/settings/advanced/delete', repo_route=True) - config.add_view( - RepoSettingsAdvancedView, - attr='edit_advanced_delete', - route_name='edit_repo_advanced_delete', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_advanced", + route_name="edit_repo_advanced", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_advanced_locking', - pattern='/{repo_name:.*?[^/]}/settings/advanced/locking', repo_route=True) + name="edit_repo_advanced_archive", pattern="/{repo_name:.*?[^/]}/settings/advanced/archive", repo_route=True + ) config.add_view( RepoSettingsAdvancedView, - attr='edit_advanced_toggle_locking', - route_name='edit_repo_advanced_locking', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_advanced_archive", + route_name="edit_repo_advanced_archive", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_advanced_journal', - pattern='/{repo_name:.*?[^/]}/settings/advanced/journal', repo_route=True) + name="edit_repo_advanced_delete", pattern="/{repo_name:.*?[^/]}/settings/advanced/delete", repo_route=True + ) config.add_view( RepoSettingsAdvancedView, - attr='edit_advanced_journal', - route_name='edit_repo_advanced_journal', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') - - config.add_route( - name='edit_repo_advanced_fork', - pattern='/{repo_name:.*?[^/]}/settings/advanced/fork', repo_route=True) - config.add_view( - RepoSettingsAdvancedView, - attr='edit_advanced_fork', - route_name='edit_repo_advanced_fork', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_advanced_delete", + route_name="edit_repo_advanced_delete", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_advanced_hooks', - pattern='/{repo_name:.*?[^/]}/settings/advanced/hooks', repo_route=True) + name="edit_repo_advanced_locking", pattern="/{repo_name:.*?[^/]}/settings/advanced/locking", repo_route=True + ) config.add_view( RepoSettingsAdvancedView, - attr='edit_advanced_install_hooks', - route_name='edit_repo_advanced_hooks', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_advanced_toggle_locking", + route_name="edit_repo_advanced_locking", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) + + config.add_route( + name="edit_repo_advanced_journal", pattern="/{repo_name:.*?[^/]}/settings/advanced/journal", repo_route=True + ) + config.add_view( + RepoSettingsAdvancedView, + attr="edit_advanced_journal", + route_name="edit_repo_advanced_journal", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) + + config.add_route( + name="edit_repo_advanced_fork", pattern="/{repo_name:.*?[^/]}/settings/advanced/fork", repo_route=True + ) + config.add_view( + RepoSettingsAdvancedView, + attr="edit_advanced_fork", + route_name="edit_repo_advanced_fork", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) + + config.add_route( + name="edit_repo_advanced_hooks", pattern="/{repo_name:.*?[^/]}/settings/advanced/hooks", repo_route=True + ) + config.add_view( + RepoSettingsAdvancedView, + attr="edit_advanced_install_hooks", + route_name="edit_repo_advanced_hooks", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # Caches - config.add_route( - name='edit_repo_caches', - pattern='/{repo_name:.*?[^/]}/settings/caches', repo_route=True) + config.add_route(name="edit_repo_caches", pattern="/{repo_name:.*?[^/]}/settings/caches", repo_route=True) config.add_view( RepoCachesView, - attr='repo_caches', - route_name='edit_repo_caches', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') - config.add_view( - RepoCachesView, - attr='repo_caches_purge', - route_name='edit_repo_caches', request_method='POST') + attr="repo_caches", + route_name="edit_repo_caches", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) + config.add_view(RepoCachesView, attr="repo_caches_purge", route_name="edit_repo_caches", request_method="POST") # Permissions - config.add_route( - name='edit_repo_perms', - pattern='/{repo_name:.*?[^/]}/settings/permissions', repo_route=True) + config.add_route(name="edit_repo_perms", pattern="/{repo_name:.*?[^/]}/settings/permissions", repo_route=True) config.add_view( RepoSettingsPermissionsView, - attr='edit_permissions', - route_name='edit_repo_perms', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_permissions", + route_name="edit_repo_perms", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_view( RepoSettingsPermissionsView, - attr='edit_permissions_update', - route_name='edit_repo_perms', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="edit_permissions_update", + route_name="edit_repo_perms", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_perms_set_private', - pattern='/{repo_name:.*?[^/]}/settings/permissions/set_private', repo_route=True) + name="edit_repo_perms_set_private", + pattern="/{repo_name:.*?[^/]}/settings/permissions/set_private", + repo_route=True, + ) config.add_view( RepoSettingsPermissionsView, - attr='edit_permissions_set_private_repo', - route_name='edit_repo_perms_set_private', request_method='POST', - renderer='json_ext') + attr="edit_permissions_set_private_repo", + route_name="edit_repo_perms_set_private", + request_method="POST", + renderer="json_ext", + ) # Permissions Branch (EE feature) config.add_route( - name='edit_repo_perms_branch', - pattern='/{repo_name:.*?[^/]}/settings/branch_permissions', repo_route=True) + name="edit_repo_perms_branch", pattern="/{repo_name:.*?[^/]}/settings/branch_permissions", repo_route=True + ) config.add_view( RepoSettingsBranchPermissionsView, - attr='branch_permissions', - route_name='edit_repo_perms_branch', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="branch_permissions", + route_name="edit_repo_perms_branch", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_perms_branch_delete', - pattern='/{repo_name:.*?[^/]}/settings/branch_permissions/{rule_id}/delete', - repo_route=True) + name="edit_repo_perms_branch_delete", + pattern="/{repo_name:.*?[^/]}/settings/branch_permissions/{rule_id}/delete", + repo_route=True, + ) ## Only implemented in EE # Maintenance - config.add_route( - name='edit_repo_maintenance', - pattern='/{repo_name:.*?[^/]}/settings/maintenance', repo_route=True) + config.add_route(name="edit_repo_maintenance", pattern="/{repo_name:.*?[^/]}/settings/maintenance", repo_route=True) config.add_view( RepoMaintenanceView, - attr='repo_maintenance', - route_name='edit_repo_maintenance', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_maintenance", + route_name="edit_repo_maintenance", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_maintenance_execute', - pattern='/{repo_name:.*?[^/]}/settings/maintenance/execute', repo_route=True) + name="edit_repo_maintenance_execute", + pattern="/{repo_name:.*?[^/]}/settings/maintenance/execute", + repo_route=True, + ) config.add_view( RepoMaintenanceView, - attr='repo_maintenance_execute', - route_name='edit_repo_maintenance_execute', request_method='GET', - renderer='json', xhr=True) + attr="repo_maintenance_execute", + route_name="edit_repo_maintenance_execute", + request_method="GET", + renderer="json", + xhr=True, + ) # Fields - config.add_route( - name='edit_repo_fields', - pattern='/{repo_name:.*?[^/]}/settings/fields', repo_route=True) + config.add_route(name="edit_repo_fields", pattern="/{repo_name:.*?[^/]}/settings/fields", repo_route=True) config.add_view( RepoSettingsFieldsView, - attr='repo_field_edit', - route_name='edit_repo_fields', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_field_edit", + route_name="edit_repo_fields", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_fields_create', - pattern='/{repo_name:.*?[^/]}/settings/fields/create', repo_route=True) + name="edit_repo_fields_create", pattern="/{repo_name:.*?[^/]}/settings/fields/create", repo_route=True + ) config.add_view( RepoSettingsFieldsView, - attr='repo_field_create', - route_name='edit_repo_fields_create', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_field_create", + route_name="edit_repo_fields_create", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_fields_delete', - pattern='/{repo_name:.*?[^/]}/settings/fields/{field_id}/delete', repo_route=True) + name="edit_repo_fields_delete", + pattern="/{repo_name:.*?[^/]}/settings/fields/{field_id}/delete", + repo_route=True, + ) config.add_view( RepoSettingsFieldsView, - attr='repo_field_delete', - route_name='edit_repo_fields_delete', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_field_delete", + route_name="edit_repo_fields_delete", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # quick actions: locking config.add_route( - name='repo_settings_quick_actions', - pattern='/{repo_name:.*?[^/]}/settings/quick-action', repo_route=True) + name="repo_settings_quick_actions", pattern="/{repo_name:.*?[^/]}/settings/quick-action", repo_route=True + ) config.add_view( RepoSettingsView, - attr='repo_settings_quick_actions', - route_name='repo_settings_quick_actions', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_settings_quick_actions", + route_name="repo_settings_quick_actions", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # Remote - config.add_route( - name='edit_repo_remote', - pattern='/{repo_name:.*?[^/]}/settings/remote', repo_route=True) + config.add_route(name="edit_repo_remote", pattern="/{repo_name:.*?[^/]}/settings/remote", repo_route=True) config.add_view( RepoSettingsRemoteView, - attr='repo_remote_edit_form', - route_name='edit_repo_remote', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_remote_edit_form", + route_name="edit_repo_remote", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) - config.add_route( - name='edit_repo_remote_pull', - pattern='/{repo_name:.*?[^/]}/settings/remote/pull', repo_route=True) + config.add_route(name="edit_repo_remote_pull", pattern="/{repo_name:.*?[^/]}/settings/remote/pull", repo_route=True) config.add_view( RepoSettingsRemoteView, - attr='repo_remote_pull_changes', - route_name='edit_repo_remote_pull', request_method='POST', - renderer=None) + attr="repo_remote_pull_changes", + route_name="edit_repo_remote_pull", + request_method="POST", + renderer=None, + ) - config.add_route( - name='edit_repo_remote_push', - pattern='/{repo_name:.*?[^/]}/settings/remote/push', repo_route=True) + config.add_route(name="edit_repo_remote_push", pattern="/{repo_name:.*?[^/]}/settings/remote/push", repo_route=True) # Statistics - config.add_route( - name='edit_repo_statistics', - pattern='/{repo_name:.*?[^/]}/settings/statistics', repo_route=True) + config.add_route(name="edit_repo_statistics", pattern="/{repo_name:.*?[^/]}/settings/statistics", repo_route=True) config.add_view( RepoSettingsView, - attr='edit_statistics_form', - route_name='edit_repo_statistics', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') - + attr="edit_statistics_form", + route_name="edit_repo_statistics", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) + config.add_route( - name='edit_repo_statistics_reset', - pattern='/{repo_name:.*?[^/]}/settings/statistics/update', repo_route=True) + name="edit_repo_statistics_reset", pattern="/{repo_name:.*?[^/]}/settings/statistics/update", repo_route=True + ) config.add_view( RepoSettingsView, - attr='repo_statistics_reset', - route_name='edit_repo_statistics_reset', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_statistics_reset", + route_name="edit_repo_statistics_reset", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # Issue trackers config.add_route( - name='edit_repo_issuetracker', - pattern='/{repo_name:.*?[^/]}/settings/issue_trackers', repo_route=True) + name="edit_repo_issuetracker", pattern="/{repo_name:.*?[^/]}/settings/issue_trackers", repo_route=True + ) config.add_view( RepoSettingsIssueTrackersView, - attr='repo_issuetracker', - route_name='edit_repo_issuetracker', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') - - config.add_route( - name='edit_repo_issuetracker_test', - pattern='/{repo_name:.*?[^/]}/settings/issue_trackers/test', repo_route=True) - config.add_view( - RepoSettingsIssueTrackersView, - attr='repo_issuetracker_test', - route_name='edit_repo_issuetracker_test', request_method='POST', - renderer='string', xhr=True) + attr="repo_issuetracker", + route_name="edit_repo_issuetracker", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='edit_repo_issuetracker_delete', - pattern='/{repo_name:.*?[^/]}/settings/issue_trackers/delete', repo_route=True) + name="edit_repo_issuetracker_test", pattern="/{repo_name:.*?[^/]}/settings/issue_trackers/test", repo_route=True + ) config.add_view( RepoSettingsIssueTrackersView, - attr='repo_issuetracker_delete', - route_name='edit_repo_issuetracker_delete', request_method='POST', - renderer='json_ext', xhr=True) + attr="repo_issuetracker_test", + route_name="edit_repo_issuetracker_test", + request_method="POST", + renderer="string", + xhr=True, + ) config.add_route( - name='edit_repo_issuetracker_update', - pattern='/{repo_name:.*?[^/]}/settings/issue_trackers/update', repo_route=True) + name="edit_repo_issuetracker_delete", + pattern="/{repo_name:.*?[^/]}/settings/issue_trackers/delete", + repo_route=True, + ) config.add_view( RepoSettingsIssueTrackersView, - attr='repo_issuetracker_update', - route_name='edit_repo_issuetracker_update', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_issuetracker_delete", + route_name="edit_repo_issuetracker_delete", + request_method="POST", + renderer="json_ext", + xhr=True, + ) + + config.add_route( + name="edit_repo_issuetracker_update", + pattern="/{repo_name:.*?[^/]}/settings/issue_trackers/update", + repo_route=True, + ) + config.add_view( + RepoSettingsIssueTrackersView, + attr="repo_issuetracker_update", + route_name="edit_repo_issuetracker_update", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # VCS Settings - config.add_route( - name='edit_repo_vcs', - pattern='/{repo_name:.*?[^/]}/settings/vcs', repo_route=True) + config.add_route(name="edit_repo_vcs", pattern="/{repo_name:.*?[^/]}/settings/vcs", repo_route=True) config.add_view( RepoSettingsVcsView, - attr='repo_vcs_settings', - route_name='edit_repo_vcs', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_vcs_settings", + route_name="edit_repo_vcs", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) - config.add_route( - name='edit_repo_vcs_update', - pattern='/{repo_name:.*?[^/]}/settings/vcs/update', repo_route=True) + config.add_route(name="edit_repo_vcs_update", pattern="/{repo_name:.*?[^/]}/settings/vcs/update", repo_route=True) config.add_view( RepoSettingsVcsView, - attr='repo_settings_vcs_update', - route_name='edit_repo_vcs_update', request_method='POST', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_settings_vcs_update", + route_name="edit_repo_vcs_update", + request_method="POST", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # svn pattern config.add_route( - name='edit_repo_vcs_svn_pattern_delete', - pattern='/{repo_name:.*?[^/]}/settings/vcs/svn_pattern/delete', repo_route=True) + name="edit_repo_vcs_svn_pattern_delete", + pattern="/{repo_name:.*?[^/]}/settings/vcs/svn_pattern/delete", + repo_route=True, + ) config.add_view( RepoSettingsVcsView, - attr='repo_settings_delete_svn_pattern', - route_name='edit_repo_vcs_svn_pattern_delete', request_method='POST', - renderer='json_ext', xhr=True) + attr="repo_settings_delete_svn_pattern", + route_name="edit_repo_vcs_svn_pattern_delete", + request_method="POST", + renderer="json_ext", + xhr=True, + ) # Repo Review Rules (EE feature) - config.add_route( - name='repo_reviewers', - pattern='/{repo_name:.*?[^/]}/settings/review/rules', repo_route=True) + config.add_route(name="repo_reviewers", pattern="/{repo_name:.*?[^/]}/settings/review/rules", repo_route=True) config.add_view( RepoReviewRulesView, - attr='repo_review_rules', - route_name='repo_reviewers', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_review_rules", + route_name="repo_reviewers", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) config.add_route( - name='repo_default_reviewers_data', - pattern='/{repo_name:.*?[^/]}/settings/review/default-reviewers', repo_route=True) + name="repo_default_reviewers_data", + pattern="/{repo_name:.*?[^/]}/settings/review/default-reviewers", + repo_route=True, + ) config.add_view( RepoReviewRulesView, - attr='repo_default_reviewers_data', - route_name='repo_default_reviewers_data', request_method='GET', - renderer='json_ext') + attr="repo_default_reviewers_data", + route_name="repo_default_reviewers_data", + request_method="GET", + renderer="json_ext", + ) # Repo Automation (EE feature) - config.add_route( - name='repo_automation', - pattern='/{repo_name:.*?[^/]}/settings/automation', repo_route=True) + config.add_route(name="repo_automation", pattern="/{repo_name:.*?[^/]}/settings/automation", repo_route=True) config.add_view( RepoAutomationView, - attr='repo_automation', - route_name='repo_automation', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_automation", + route_name="repo_automation", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # Strip - config.add_route( - name='edit_repo_strip', - pattern='/{repo_name:.*?[^/]}/settings/strip', repo_route=True) + config.add_route(name="edit_repo_strip", pattern="/{repo_name:.*?[^/]}/settings/strip", repo_route=True) config.add_view( RepoStripView, - attr='strip', - route_name='edit_repo_strip', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="strip", + route_name="edit_repo_strip", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) - config.add_route( - name='strip_check', - pattern='/{repo_name:.*?[^/]}/settings/strip_check', repo_route=True) + config.add_route(name="strip_check", pattern="/{repo_name:.*?[^/]}/settings/strip_check", repo_route=True) config.add_view( - RepoStripView, - attr='strip_check', - route_name='strip_check', request_method='POST', - renderer='json', xhr=True) + RepoStripView, attr="strip_check", route_name="strip_check", request_method="POST", renderer="json", xhr=True + ) - config.add_route( - name='strip_execute', - pattern='/{repo_name:.*?[^/]}/settings/strip_execute', repo_route=True) + config.add_route(name="strip_execute", pattern="/{repo_name:.*?[^/]}/settings/strip_execute", repo_route=True) config.add_view( RepoStripView, - attr='strip_execute', - route_name='strip_execute', request_method='POST', - renderer='json', xhr=True) + attr="strip_execute", + route_name="strip_execute", + request_method="POST", + renderer="json", + xhr=True, + ) # Audit logs - config.add_route( - name='edit_repo_audit_logs', - pattern='/{repo_name:.*?[^/]}/settings/audit_logs', repo_route=True) + config.add_route(name="edit_repo_audit_logs", pattern="/{repo_name:.*?[^/]}/settings/audit_logs", repo_route=True) config.add_view( AuditLogsView, - attr='repo_audit_logs', - route_name='edit_repo_audit_logs', request_method='GET', - renderer='rhodecode:templates/admin/repos/repo_edit.mako') + attr="repo_audit_logs", + route_name="edit_repo_audit_logs", + request_method="GET", + renderer="rhodecode:templates/admin/repos/repo_edit.mako", + ) # ATOM/RSS Feed, shouldn't contain slashes for outlook compatibility - config.add_route( - name='rss_feed_home', - pattern='/{repo_name:.*?[^/]}/feed-rss', repo_route=True) - config.add_view( - RepoFeedView, - attr='rss', - route_name='rss_feed_home', request_method='GET', renderer=None) + config.add_route(name="rss_feed_home", pattern="/{repo_name:.*?[^/]}/feed-rss", repo_route=True) + config.add_view(RepoFeedView, attr="rss", route_name="rss_feed_home", request_method="GET", renderer=None) - config.add_route( - name='rss_feed_home_old', - pattern='/{repo_name:.*?[^/]}/feed/rss', repo_route=True) - config.add_view( - RepoFeedView, - attr='rss', - route_name='rss_feed_home_old', request_method='GET', renderer=None) + config.add_route(name="rss_feed_home_old", pattern="/{repo_name:.*?[^/]}/feed/rss", repo_route=True) + config.add_view(RepoFeedView, attr="rss", route_name="rss_feed_home_old", request_method="GET", renderer=None) - config.add_route( - name='atom_feed_home', - pattern='/{repo_name:.*?[^/]}/feed-atom', repo_route=True) - config.add_view( - RepoFeedView, - attr='atom', - route_name='atom_feed_home', request_method='GET', renderer=None) + config.add_route(name="atom_feed_home", pattern="/{repo_name:.*?[^/]}/feed-atom", repo_route=True) + config.add_view(RepoFeedView, attr="atom", route_name="atom_feed_home", request_method="GET", renderer=None) - config.add_route( - name='atom_feed_home_old', - pattern='/{repo_name:.*?[^/]}/feed/atom', repo_route=True) - config.add_view( - RepoFeedView, - attr='atom', - route_name='atom_feed_home_old', request_method='GET', renderer=None) + config.add_route(name="atom_feed_home_old", pattern="/{repo_name:.*?[^/]}/feed/atom", repo_route=True) + config.add_view(RepoFeedView, attr="atom", route_name="atom_feed_home_old", request_method="GET", renderer=None) # NOTE(marcink): needs to be at the end for catch-all - add_route_with_slash( - config, - name='repo_summary', - pattern='/{repo_name:.*?[^/]}', repo_route=True) + add_route_with_slash(config, name="repo_summary", pattern="/{repo_name:.*?[^/]}", repo_route=True) config.add_view( RepoSummaryView, - attr='summary', - route_name='repo_summary', request_method='GET', - renderer='rhodecode:templates/summary/summary.mako') - + attr="summary", + route_name="repo_summary", + request_method="GET", + renderer="rhodecode:templates/summary/summary.mako", + ) + # TODO(marcink): there's no such route?? config.add_view( RepoSummaryView, - attr='summary', - route_name='repo_summary_slash', request_method='GET', - renderer='rhodecode:templates/summary/summary.mako') \ No newline at end of file + attr="summary", + route_name="repo_summary_slash", + request_method="GET", + renderer="rhodecode:templates/summary/summary.mako", + ) diff --git a/rhodecode/apps/repository/tests/test_pull_requests_list.py b/rhodecode/apps/repository/tests/test_pull_requests_list.py index 24bf0e9d..325bca38 100644 --- a/rhodecode/apps/repository/tests/test_pull_requests_list.py +++ b/rhodecode/apps/repository/tests/test_pull_requests_list.py @@ -21,49 +21,49 @@ from rhodecode.tests.routes import route_path @pytest.mark.backends("git", "hg") -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestPullRequestList(object): - - @pytest.mark.parametrize('params, expected_title', [ - ({'source': 0, 'closed': 1}, 'Closed'), - ({'source': 0, 'my': 1}, 'Created by me'), - ({'source': 0, 'awaiting_review': 1}, 'Awaiting review'), - ({'source': 0, 'awaiting_my_review': 1}, 'Awaiting my review'), - ({'source': 1}, 'From this repo'), - ]) + @pytest.mark.parametrize( + "params, expected_title", + [ + ({"source": 0, "closed": 1}, "Closed"), + ({"source": 0, "my": 1}, "Created by me"), + ({"source": 0, "awaiting_review": 1}, "Awaiting review"), + ({"source": 0, "awaiting_my_review": 1}, "Awaiting my review"), + ({"source": 1}, "From this repo"), + ], + ) def test_showing_list_page(self, backend, pr_util, params, expected_title): pull_request = pr_util.create_pull_request() response = self.app.get( - route_path('pullrequest_show_all', - repo_name=pull_request.target_repo.repo_name, - params=params)) + route_path("pullrequest_show_all", repo_name=pull_request.target_repo.repo_name, params=params) + ) assert_response = response.assert_response() - element = assert_response.get_element('.title .active') + element = assert_response.get_element(".title .active") element_text = element.text_content() assert expected_title == element_text def test_showing_list_page_data(self, backend, pr_util, xhr_header): pull_request = pr_util.create_pull_request() response = self.app.get( - route_path('pullrequest_show_all_data', - repo_name=pull_request.target_repo.repo_name), - extra_environ=xhr_header) + route_path("pullrequest_show_all_data", repo_name=pull_request.target_repo.repo_name), + extra_environ=xhr_header, + ) - assert response.json['recordsTotal'] == 1 - assert response.json['data'][0]['description'] == 'Description' + assert response.json["recordsTotal"] == 1 + assert response.json["data"][0]["description"] == "Description" def test_description_is_escaped_on_index_page(self, backend, pr_util, xhr_header): xss_description = "" pull_request = pr_util.create_pull_request(description=xss_description) response = self.app.get( - route_path('pullrequest_show_all_data', - repo_name=pull_request.target_repo.repo_name), - extra_environ=xhr_header) + route_path("pullrequest_show_all_data", repo_name=pull_request.target_repo.repo_name), + extra_environ=xhr_header, + ) - assert response.json['recordsTotal'] == 1 - assert response.json['data'][0]['description'] == \ - "<script>alert('Hi!')</script>" + assert response.json["recordsTotal"] == 1 + assert response.json["data"][0]["description"] == "<script>alert('Hi!')</script>" diff --git a/rhodecode/apps/repository/tests/test_repo_bookmarks.py b/rhodecode/apps/repository/tests/test_repo_bookmarks.py index 9b72c6a7..b030a6e9 100644 --- a/rhodecode/apps/repository/tests/test_repo_bookmarks.py +++ b/rhodecode/apps/repository/tests/test_repo_bookmarks.py @@ -21,20 +21,15 @@ from rhodecode.model.db import Repository from rhodecode.tests.routes import route_path - -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestBookmarks(object): - def test_index(self, backend): - if backend.alias == 'hg': - response = self.app.get( - route_path('bookmarks_home', repo_name=backend.repo_name)) + if backend.alias == "hg": + response = self.app.get(route_path("bookmarks_home", repo_name=backend.repo_name)) repo = Repository.get_by_repo_name(backend.repo_name) for commit_id, obj_name in repo.scm_instance().bookmarks.items(): assert commit_id in response assert obj_name in response else: - self.app.get( - route_path('bookmarks_home', repo_name=backend.repo_name), - status=404) + self.app.get(route_path("bookmarks_home", repo_name=backend.repo_name), status=404) diff --git a/rhodecode/apps/repository/tests/test_repo_branches.py b/rhodecode/apps/repository/tests/test_repo_branches.py index 4cb67e27..c7f6aebc 100644 --- a/rhodecode/apps/repository/tests/test_repo_branches.py +++ b/rhodecode/apps/repository/tests/test_repo_branches.py @@ -22,12 +22,10 @@ from rhodecode.tests.routes import route_path from rhodecode.tests import assert_session_flash -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestBranchesController(object): - def test_index(self, backend): - response = self.app.get( - route_path('branches_home', repo_name=backend.repo_name)) + response = self.app.get(route_path("branches_home", repo_name=backend.repo_name)) repo = Repository.get_by_repo_name(backend.repo_name) @@ -36,48 +34,53 @@ class TestBranchesController(object): assert obj_name in response def test_landing_branch_delete(self, backend, csrf_token): - if backend.alias == 'svn': + if backend.alias == "svn": pytest.skip("Not supported yet") branch_related_data_per_backend = { - 'git': {'name': 'master'}, - 'hg': {'name': 'default'}, + "git": {"name": "master"}, + "hg": {"name": "default"}, } response = self.app.post( - route_path('branch_remove', repo_name=backend.repo_name, - branch_name=branch_related_data_per_backend[backend.alias]['name']), - params={'csrf_token': csrf_token}, status=302) + route_path( + "branch_remove", + repo_name=backend.repo_name, + branch_name=branch_related_data_per_backend[backend.alias]["name"], + ), + params={"csrf_token": csrf_token}, + status=302, + ) assert_session_flash( response, - f"This branch {branch_related_data_per_backend[backend.alias]['name']} cannot be removed as it's currently set as landing branch" + f"This branch {branch_related_data_per_backend[backend.alias]['name']} cannot be removed as it's currently set as landing branch", ) def test_delete_branch_by_repo_owner(self, backend, csrf_token): - if backend.alias in ('svn', 'hg'): + if backend.alias in ("svn", "hg"): pytest.skip("Skipping for hg and svn") - branch_to_be_removed = 'remove_me' + branch_to_be_removed = "remove_me" repo = Repository.get_by_repo_name(backend.repo_name) repo.scm_instance()._create_branch(branch_to_be_removed, repo.scm_instance().commit_ids[1]) response = self.app.post( - route_path('branch_remove', repo_name=backend.repo_name, - branch_name=branch_to_be_removed), - params={'csrf_token': csrf_token}, status=302) + route_path("branch_remove", repo_name=backend.repo_name, branch_name=branch_to_be_removed), + params={"csrf_token": csrf_token}, + status=302, + ) assert_session_flash(response, f"Branch {branch_to_be_removed} has been successfully deleted") def test_delete_branch_by_not_repo_owner(self, backend, csrf_token): - username = 'test_regular' - pwd = 'test12' + username = "test_regular" + pwd = "test12" branch_related_data_per_backend = { - 'git': {'name': 'master', 'action': 'deleted'}, - 'hg': {'name': 'stable', 'action': 'closed'}, + "git": {"name": "master", "action": "deleted"}, + "hg": {"name": "stable", "action": "closed"}, } - if backend.alias == 'svn': + if backend.alias == "svn": pytest.skip("Not supported yet") - self.app.post(route_path('login'), - {'username': username, - 'password': pwd}) - selected_branch = branch_related_data_per_backend[backend.alias]['name'] + self.app.post(route_path("login"), {"username": username, "password": pwd}) + selected_branch = branch_related_data_per_backend[backend.alias]["name"] response = self.app.post( - route_path('branch_remove', repo_name=backend.repo_name, - branch_name=selected_branch), - params={'csrf_token': csrf_token, 'username': username, 'password': pwd}, status=404) + route_path("branch_remove", repo_name=backend.repo_name, branch_name=selected_branch), + params={"csrf_token": csrf_token, "username": username, "password": pwd}, + status=404, + ) assert response.status_code == 404 diff --git a/rhodecode/apps/repository/tests/test_repo_changelog.py b/rhodecode/apps/repository/tests/test_repo_changelog.py index 9bca23a5..42523df6 100644 --- a/rhodecode/apps/repository/tests/test_repo_changelog.py +++ b/rhodecode/apps/repository/tests/test_repo_changelog.py @@ -34,11 +34,9 @@ def assert_commits_on_page(response, indexes): class TestChangelogController(TestController): - def test_commits_page(self, backend): self.log_user() - response = self.app.get( - route_path('repo_commits', repo_name=backend.repo_name)) + response = self.app.get(route_path("repo_commits", repo_name=backend.repo_name)) first_idx = -1 last_idx = -DEFAULT_CHANGELOG_SIZE @@ -46,101 +44,89 @@ class TestChangelogController(TestController): def test_changelog(self, backend): self.log_user() - response = self.app.get( - route_path('repo_changelog', repo_name=backend.repo_name)) + response = self.app.get(route_path("repo_changelog", repo_name=backend.repo_name)) first_idx = -1 last_idx = -DEFAULT_CHANGELOG_SIZE - self.assert_commit_range_on_page( - response, first_idx, last_idx, backend) + self.assert_commit_range_on_page(response, first_idx, last_idx, backend) @pytest.mark.backends("hg", "git") def test_changelog_filtered_by_branch(self, backend): self.log_user() self.app.get( - route_path('repo_changelog', repo_name=backend.repo_name, - params=dict(branch=backend.default_branch_name)), - status=200) + route_path("repo_changelog", repo_name=backend.repo_name, params=dict(branch=backend.default_branch_name)), + status=200, + ) @pytest.mark.backends("hg", "git") def test_commits_filtered_by_branch(self, backend): self.log_user() self.app.get( - route_path('repo_commits', repo_name=backend.repo_name, - params=dict(branch=backend.default_branch_name)), - status=200) + route_path("repo_commits", repo_name=backend.repo_name, params=dict(branch=backend.default_branch_name)), + status=200, + ) @pytest.mark.backends("svn") def test_changelog_filtered_by_branch_svn(self, autologin_user, backend): - repo = backend['svn-simple-layout'] + repo = backend["svn-simple-layout"] response = self.app.get( - route_path('repo_changelog', repo_name=repo.repo_name, - params=dict(branch='trunk')), - status=200) + route_path("repo_changelog", repo_name=repo.repo_name, params=dict(branch="trunk")), status=200 + ) assert_commits_on_page(response, indexes=[15, 12, 7, 3, 2, 1]) def test_commits_filtered_by_wrong_branch(self, backend): self.log_user() - branch = 'wrong-branch-name' + branch = "wrong-branch-name" response = self.app.get( - route_path('repo_commits', repo_name=backend.repo_name, - params=dict(branch=branch)), - status=302) - expected_url = '/{repo}/commits/{branch}'.format( - repo=backend.repo_name, branch=branch) + route_path("repo_commits", repo_name=backend.repo_name, params=dict(branch=branch)), status=302 + ) + expected_url = "/{repo}/commits/{branch}".format(repo=backend.repo_name, branch=branch) assert expected_url in response.location response = response.follow() - expected_warning = f'Branch {branch} is not found.' + expected_warning = f"Branch {branch} is not found." assert expected_warning in response.text @pytest.mark.xfail_backends("svn", reason="Depends on branch support") def test_changelog_filtered_by_branch_with_merges(self, autologin_user, backend): - # Note: The changelog of branch "b" does not contain the commit "a1" # although this is a parent of commit "b1". And branch "b" has commits # which have a smaller index than commit "a1". commits = [ - {'message': 'a', 'branch': 'master'}, - {'message': 'b', 'branch': 'b'}, - {'message': 'a1', 'parents': ['a'], 'branch': 'master'}, - {'message': 'b1', 'branch': 'b', 'parents': ['b', 'a1']}, + {"message": "a", "branch": "master"}, + {"message": "b", "branch": "b"}, + {"message": "a1", "parents": ["a"], "branch": "master"}, + {"message": "b1", "branch": "b", "parents": ["b", "a1"]}, ] backend.create_repo(commits) - self.app.get( - route_path('repo_changelog', repo_name=backend.repo_name, - params=dict(branch='b')), - status=200) + self.app.get(route_path("repo_changelog", repo_name=backend.repo_name, params=dict(branch="b")), status=200) @pytest.mark.backends("hg") def test_commits_closed_branches(self, autologin_user, backend): - repo = backend['closed_branch'] + repo = backend["closed_branch"] response = self.app.get( - route_path('repo_commits', repo_name=repo.repo_name, - params=dict(branch='experimental')), - status=200) + route_path("repo_commits", repo_name=repo.repo_name, params=dict(branch="experimental")), status=200 + ) assert_commits_on_page(response, indexes=[3, 1]) def test_changelog_pagination(self, backend): self.log_user() # pagination, walk up to page 6 - changelog_url = route_path( - 'repo_commits', repo_name=backend.repo_name) + changelog_url = route_path("repo_commits", repo_name=backend.repo_name) for page in range(1, 7): - response = self.app.get(changelog_url, {'page': page}) + response = self.app.get(changelog_url, {"page": page}) first_idx = -DEFAULT_CHANGELOG_SIZE * (page - 1) - 1 last_idx = -DEFAULT_CHANGELOG_SIZE * page self.assert_commit_range_on_page(response, first_idx, last_idx, backend) - def assert_commit_range_on_page( - self, response, first_idx, last_idx, backend): + def assert_commit_range_on_page(self, response, first_idx, last_idx, backend): input_template = ( - """""" ) @@ -150,55 +136,55 @@ class TestChangelogController(TestController): first_commit_on_page = repo.get_commit(commit_idx=first_idx) response.mustcontain( - input_template % {'raw_id': first_commit_on_page.raw_id, - 'idx': first_commit_on_page.idx, - 'short_id': first_commit_on_page.short_id}) - - response.mustcontain(commit_span_template % ( - first_commit_on_page.idx, first_commit_on_page.short_id) + input_template + % { + "raw_id": first_commit_on_page.raw_id, + "idx": first_commit_on_page.idx, + "short_id": first_commit_on_page.short_id, + } ) + response.mustcontain(commit_span_template % (first_commit_on_page.idx, first_commit_on_page.short_id)) + last_commit_on_page = repo.get_commit(commit_idx=last_idx) response.mustcontain( - input_template % {'raw_id': last_commit_on_page.raw_id, - 'idx': last_commit_on_page.idx, - 'short_id': last_commit_on_page.short_id}) - response.mustcontain(commit_span_template % ( - last_commit_on_page.idx, last_commit_on_page.short_id) + input_template + % { + "raw_id": last_commit_on_page.raw_id, + "idx": last_commit_on_page.idx, + "short_id": last_commit_on_page.short_id, + } ) + response.mustcontain(commit_span_template % (last_commit_on_page.idx, last_commit_on_page.short_id)) first_commit_of_next_page = repo.get_commit(commit_idx=last_idx - 1) first_span_of_next_page = commit_span_template % ( - first_commit_of_next_page.idx, first_commit_of_next_page.short_id) + first_commit_of_next_page.idx, + first_commit_of_next_page.short_id, + ) assert first_span_of_next_page not in response - @pytest.mark.parametrize('test_path', [ - 'vcs/exceptions.py', - '/vcs/exceptions.py', - '//vcs/exceptions.py' - ]) + @pytest.mark.parametrize("test_path", ["vcs/exceptions.py", "/vcs/exceptions.py", "//vcs/exceptions.py"]) def test_commits_with_filenode(self, backend, test_path): self.log_user() response = self.app.get( - route_path('repo_commits_file', repo_name=backend.repo_name, - commit_id='tip', f_path=test_path), - ) + route_path("repo_commits_file", repo_name=backend.repo_name, commit_id="tip", f_path=test_path), + ) # history commits messages - response.mustcontain('Added exceptions module, this time for real') - response.mustcontain('Added not implemented hg backend test case') - response.mustcontain('Added BaseChangeset class') + response.mustcontain("Added exceptions module, this time for real") + response.mustcontain("Added not implemented hg backend test case") + response.mustcontain("Added BaseChangeset class") def test_commits_with_filenode_that_is_dirnode(self, backend): self.log_user() self.app.get( - route_path('repo_commits_file', repo_name=backend.repo_name, - commit_id='tip', f_path='/tests'), - status=302) + route_path("repo_commits_file", repo_name=backend.repo_name, commit_id="tip", f_path="/tests"), status=302 + ) def test_commits_with_filenode_not_existing(self, backend): self.log_user() self.app.get( - route_path('repo_commits_file', repo_name=backend.repo_name, - commit_id='tip', f_path='wrong_path'), - status=302) + route_path("repo_commits_file", repo_name=backend.repo_name, commit_id="tip", f_path="wrong_path"), + status=302, + ) diff --git a/rhodecode/apps/repository/tests/test_repo_commit_comments.py b/rhodecode/apps/repository/tests/test_repo_commit_comments.py index 097208ef..bacb68d1 100644 --- a/rhodecode/apps/repository/tests/test_repo_commit_comments.py +++ b/rhodecode/apps/repository/tests/test_repo_commit_comments.py @@ -25,10 +25,8 @@ from rhodecode.model.meta import Session from rhodecode.lib import helpers as h - @pytest.mark.backends("git", "hg", "svn") class TestRepoCommitCommentsView(TestController): - @pytest.fixture(autouse=True) def prepare(self, request, baseapp): for x in ChangesetComment.query().all(): @@ -50,23 +48,19 @@ class TestRepoCommitCommentsView(TestController): Session().delete(x) Session().commit() - @pytest.mark.parametrize('comment_type', ChangesetComment.COMMENT_TYPES) + @pytest.mark.parametrize("comment_type", ChangesetComment.COMMENT_TYPES) def test_create(self, comment_type, backend): self.log_user() - commit = backend.repo.get_commit('300') + commit = backend.repo.get_commit("300") commit_id = commit.raw_id - text = 'CommentOnCommit' + text = "CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token, - 'comment_type': comment_type} + params = {"text": text, "csrf_token": self.csrf_token, "comment_type": comment_type} self.app.post( - route_path('repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) - response = self.app.get( - route_path('repo_commit', - repo_name=backend.repo_name, commit_id=commit_id)) + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) # test DB assert ChangesetComment.query().count() == 1 @@ -81,54 +75,55 @@ class TestRepoCommitCommentsView(TestController): assert notification.type_ == Notification.TYPE_CHANGESET_COMMENT author = notification.created_by_user.username_and_name - sbj = '@{0} left a {1} on commit `{2}` in the `{3}` repository'.format( - author, comment_type, h.show_id(commit), backend.repo_name) + sbj = "@{0} left a {1} on commit `{2}` in the `{3}` repository".format( + author, comment_type, h.show_id(commit), backend.repo_name + ) assert sbj == notification.subject - lnk = ('/{0}/changeset/{1}#comment-{2}'.format( - backend.repo_name, commit_id, comment_id)) + lnk = "/{0}/changeset/{1}#comment-{2}".format(backend.repo_name, commit_id, comment_id) assert lnk in notification.body - @pytest.mark.parametrize('comment_type', ChangesetComment.COMMENT_TYPES) + @pytest.mark.parametrize("comment_type", ChangesetComment.COMMENT_TYPES) def test_create_inline(self, comment_type, backend): self.log_user() - commit = backend.repo.get_commit('300') + commit = backend.repo.get_commit("300") commit_id = commit.raw_id - text = 'CommentOnCommit' - f_path = 'vcs/web/simplevcs/views/repository.py' - line = 'n1' + text = "CommentOnCommit" + f_path = "vcs/web/simplevcs/views/repository.py" + line = "n1" - params = {'text': text, 'f_path': f_path, 'line': line, - 'comment_type': comment_type, - 'csrf_token': self.csrf_token} + params = { + "text": text, + "f_path": f_path, + "line": line, + "comment_type": comment_type, + "csrf_token": self.csrf_token, + } self.app.post( - route_path('repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) - response = self.app.get( - route_path('repo_commit', - repo_name=backend.repo_name, commit_id=commit_id)) + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) # test DB assert ChangesetComment.query().count() == 1 assert_comment_links(response, 0, ChangesetComment.query().count()) - if backend.alias == 'svn': + if backend.alias == "svn": response.mustcontain( - '''data-f-path="vcs/commands/summary.py" ''' + """data-f-path="vcs/commands/summary.py" """ '''data-anchor-id="c-300-ad05457a43f8"''' ) - if backend.alias == 'git': + if backend.alias == "git": response.mustcontain( - '''data-f-path="vcs/backends/hg.py" ''' + """data-f-path="vcs/backends/hg.py" """ '''data-anchor-id="c-883e775e89ea-9c390eb52cd6"''' ) - if backend.alias == 'hg': + if backend.alias == "hg": response.mustcontain( - '''data-f-path="vcs/backends/hg.py" ''' + """data-f-path="vcs/backends/hg.py" """ '''data-anchor-id="c-e58d85a3973b-9c390eb52cd6"''' ) @@ -142,31 +137,28 @@ class TestRepoCommitCommentsView(TestController): assert comment.revision == commit_id author = notification.created_by_user.username_and_name - sbj = '@{0} left a {1} on file `{2}` in commit `{3}` in the `{4}` repository'.format( - author, comment_type, f_path, h.show_id(commit), backend.repo_name) + sbj = "@{0} left a {1} on file `{2}` in commit `{3}` in the `{4}` repository".format( + author, comment_type, f_path, h.show_id(commit), backend.repo_name + ) assert sbj == notification.subject - lnk = ('/{0}/changeset/{1}#comment-{2}'.format( - backend.repo_name, commit_id, comment.comment_id)) + lnk = "/{0}/changeset/{1}#comment-{2}".format(backend.repo_name, commit_id, comment.comment_id) assert lnk in notification.body - assert 'on line n1' in notification.body + assert "on line n1" in notification.body def test_create_with_mention(self, backend): self.log_user() - commit_id = backend.repo.get_commit('300').raw_id - text = '@test_regular check CommentOnCommit' + commit_id = backend.repo.get_commit("300").raw_id + text = "@test_regular check CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token} + params = {"text": text, "csrf_token": self.csrf_token} self.app.post( - route_path('repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) - response = self.app.get( - route_path('repo_commit', - repo_name=backend.repo_name, commit_id=commit_id)) + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) # test DB assert ChangesetComment.query().count() == 1 assert_comment_links(response, ChangesetComment.query().count(), 0) @@ -177,28 +169,23 @@ class TestRepoCommitCommentsView(TestController): users = [x.username for x in notification.recipients] # test_regular gets notification by @mention - assert sorted(users) == ['test_admin', 'test_regular'] + assert sorted(users) == ["test_admin", "test_regular"] def test_create_with_status_change(self, backend): self.log_user() - commit = backend.repo.get_commit('300') + commit = backend.repo.get_commit("300") commit_id = commit.raw_id - text = 'CommentOnCommit' - f_path = 'vcs/web/simplevcs/views/repository.py' - line = 'n1' + text = "CommentOnCommit" + f_path = "vcs/web/simplevcs/views/repository.py" + line = "n1" - params = {'text': text, 'changeset_status': 'approved', - 'csrf_token': self.csrf_token} + params = {"text": text, "changeset_status": "approved", "csrf_token": self.csrf_token} self.app.post( - route_path( - 'repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) - response = self.app.get( - route_path('repo_commit', - repo_name=backend.repo_name, commit_id=commit_id)) + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) # test DB assert ChangesetComment.query().count() == 1 @@ -213,89 +200,81 @@ class TestRepoCommitCommentsView(TestController): assert notification.type_ == Notification.TYPE_CHANGESET_COMMENT author = notification.created_by_user.username_and_name - sbj = '[status: Approved] @{0} left a note on commit `{1}` in the `{2}` repository'.format( - author, h.show_id(commit), backend.repo_name) + sbj = "[status: Approved] @{0} left a note on commit `{1}` in the `{2}` repository".format( + author, h.show_id(commit), backend.repo_name + ) assert sbj == notification.subject - lnk = ('/{0}/changeset/{1}#comment-{2}'.format( - backend.repo_name, commit_id, comment_id)) + lnk = "/{0}/changeset/{1}#comment-{2}".format(backend.repo_name, commit_id, comment_id) assert lnk in notification.body def test_delete(self, backend): self.log_user() - commit_id = backend.repo.get_commit('300').raw_id - text = 'CommentOnCommit' + commit_id = backend.repo.get_commit("300").raw_id + text = "CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token} + params = {"text": text, "csrf_token": self.csrf_token} self.app.post( - route_path( - 'repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) comments = ChangesetComment.query().all() assert len(comments) == 1 comment_id = comments[0].comment_id self.app.post( - route_path('repo_commit_comment_delete', - repo_name=backend.repo_name, - commit_id=commit_id, - comment_id=comment_id), - params={'csrf_token': self.csrf_token}) + route_path( + "repo_commit_comment_delete", repo_name=backend.repo_name, commit_id=commit_id, comment_id=comment_id + ), + params={"csrf_token": self.csrf_token}, + ) comments = ChangesetComment.query().all() assert len(comments) == 0 - response = self.app.get( - route_path('repo_commit', - repo_name=backend.repo_name, commit_id=commit_id)) + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) assert_comment_links(response, 0, 0) def test_edit(self, backend): self.log_user() - commit_id = backend.repo.get_commit('300').raw_id - text = 'CommentOnCommit' + commit_id = backend.repo.get_commit("300").raw_id + text = "CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token} + params = {"text": text, "csrf_token": self.csrf_token} self.app.post( - route_path( - 'repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) comments = ChangesetComment.query().all() assert len(comments) == 1 comment_id = comments[0].comment_id - test_text = 'test_text' + test_text = "test_text" self.app.post( route_path( - 'repo_commit_comment_edit', + "repo_commit_comment_edit", repo_name=backend.repo_name, commit_id=commit_id, comment_id=comment_id, ), params={ - 'csrf_token': self.csrf_token, - 'text': test_text, - 'version': '0', - }) + "csrf_token": self.csrf_token, + "text": test_text, + "version": "0", + }, + ) - text_form_db = ChangesetComment.query().filter( - ChangesetComment.comment_id == comment_id).first().text + text_form_db = ChangesetComment.query().filter(ChangesetComment.comment_id == comment_id).first().text assert test_text == text_form_db def test_edit_without_change(self, backend): self.log_user() - commit_id = backend.repo.get_commit('300').raw_id - text = 'CommentOnCommit' + commit_id = backend.repo.get_commit("300").raw_id + text = "CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token} + params = {"text": text, "csrf_token": self.csrf_token} self.app.post( - route_path( - 'repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) comments = ChangesetComment.query().all() assert len(comments) == 1 @@ -303,15 +282,15 @@ class TestRepoCommitCommentsView(TestController): response = self.app.post( route_path( - 'repo_commit_comment_edit', + "repo_commit_comment_edit", repo_name=backend.repo_name, commit_id=commit_id, comment_id=comment_id, ), params={ - 'csrf_token': self.csrf_token, - 'text': text, - 'version': '0', + "csrf_token": self.csrf_token, + "text": text, + "version": "0", }, status=404, ) @@ -319,71 +298,67 @@ class TestRepoCommitCommentsView(TestController): def test_edit_try_edit_already_edited(self, backend): self.log_user() - commit_id = backend.repo.get_commit('300').raw_id - text = 'CommentOnCommit' + commit_id = backend.repo.get_commit("300").raw_id + text = "CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token} + params = {"text": text, "csrf_token": self.csrf_token} self.app.post( - route_path( - 'repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id - ), + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params, ) comments = ChangesetComment.query().all() assert len(comments) == 1 comment_id = comments[0].comment_id - test_text = 'test_text' + test_text = "test_text" self.app.post( route_path( - 'repo_commit_comment_edit', + "repo_commit_comment_edit", repo_name=backend.repo_name, commit_id=commit_id, comment_id=comment_id, ), params={ - 'csrf_token': self.csrf_token, - 'text': test_text, - 'version': '0', - } + "csrf_token": self.csrf_token, + "text": test_text, + "version": "0", + }, ) - test_text_v2 = 'test_v2' + test_text_v2 = "test_v2" response = self.app.post( route_path( - 'repo_commit_comment_edit', + "repo_commit_comment_edit", repo_name=backend.repo_name, commit_id=commit_id, comment_id=comment_id, ), params={ - 'csrf_token': self.csrf_token, - 'text': test_text_v2, - 'version': '0', + "csrf_token": self.csrf_token, + "text": test_text_v2, + "version": "0", }, status=409, ) assert response.status_int == 409 - text_form_db = ChangesetComment.query().filter( - ChangesetComment.comment_id == comment_id).first().text + text_form_db = ChangesetComment.query().filter(ChangesetComment.comment_id == comment_id).first().text assert test_text == text_form_db assert test_text_v2 != text_form_db def test_edit_forbidden_for_immutable_comments(self, backend): self.log_user() - commit_id = backend.repo.get_commit('300').raw_id - text = 'CommentOnCommit' + commit_id = backend.repo.get_commit("300").raw_id + text = "CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token, 'version': '0'} + params = {"text": text, "csrf_token": self.csrf_token, "version": "0"} self.app.post( route_path( - 'repo_commit_comment_create', + "repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id, ), - params=params + params=params, ) comments = ChangesetComment.query().all() @@ -397,14 +372,14 @@ class TestRepoCommitCommentsView(TestController): response = self.app.post( route_path( - 'repo_commit_comment_edit', + "repo_commit_comment_edit", repo_name=backend.repo_name, commit_id=commit_id, comment_id=comment_id, ), params={ - 'csrf_token': self.csrf_token, - 'text': 'test_text', + "csrf_token": self.csrf_token, + "text": "test_text", }, status=403, ) @@ -412,15 +387,13 @@ class TestRepoCommitCommentsView(TestController): def test_delete_forbidden_for_immutable_comments(self, backend): self.log_user() - commit_id = backend.repo.get_commit('300').raw_id - text = 'CommentOnCommit' + commit_id = backend.repo.get_commit("300").raw_id + text = "CommentOnCommit" - params = {'text': text, 'csrf_token': self.csrf_token} + params = {"text": text, "csrf_token": self.csrf_token} self.app.post( - route_path( - 'repo_commit_comment_create', - repo_name=backend.repo_name, commit_id=commit_id), - params=params) + route_path("repo_commit_comment_create", repo_name=backend.repo_name, commit_id=commit_id), params=params + ) comments = ChangesetComment.query().all() assert len(comments) == 1 @@ -432,46 +405,53 @@ class TestRepoCommitCommentsView(TestController): Session().commit() self.app.post( - route_path('repo_commit_comment_delete', - repo_name=backend.repo_name, - commit_id=commit_id, - comment_id=comment_id), - params={'csrf_token': self.csrf_token}, - status=403) + route_path( + "repo_commit_comment_delete", repo_name=backend.repo_name, commit_id=commit_id, comment_id=comment_id + ), + params={"csrf_token": self.csrf_token}, + status=403, + ) - @pytest.mark.parametrize('renderer, text_input, output', [ - ('rst', 'plain text', '

plain text

'), - ('rst', 'header\n======', '

header

'), - ('rst', '*italics*', 'italics'), - ('rst', '**bold**', 'bold'), - ('markdown', 'plain text', '

plain text

'), - ('markdown', '# header', '

header

'), - ('markdown', '*italics*', 'italics'), - ('markdown', '**bold**', 'bold'), - ], ids=['rst-plain', 'rst-header', 'rst-italics', 'rst-bold', 'md-plain', - 'md-header', 'md-italics', 'md-bold', ]) + @pytest.mark.parametrize( + "renderer, text_input, output", + [ + ("rst", "plain text", "

plain text

"), + ("rst", "header\n======", '

header

'), + ("rst", "*italics*", "italics"), + ("rst", "**bold**", "bold"), + ("markdown", "plain text", "

plain text

"), + ("markdown", "# header", "

header

"), + ("markdown", "*italics*", "italics"), + ("markdown", "**bold**", "bold"), + ], + ids=[ + "rst-plain", + "rst-header", + "rst-italics", + "rst-bold", + "md-plain", + "md-header", + "md-italics", + "md-bold", + ], + ) def test_preview(self, renderer, text_input, output, backend, xhr_header): self.log_user() - params = { - 'renderer': renderer, - 'text': text_input, - 'csrf_token': self.csrf_token - } - commit_id = '0' * 16 # fake this for tests + params = {"renderer": renderer, "text": text_input, "csrf_token": self.csrf_token} + commit_id = "0" * 16 # fake this for tests response = self.app.post( - route_path('repo_commit_comment_preview', - repo_name=backend.repo_name, commit_id=commit_id,), + route_path( + "repo_commit_comment_preview", + repo_name=backend.repo_name, + commit_id=commit_id, + ), params=params, - extra_environ=xhr_header) + extra_environ=xhr_header, + ) response.mustcontain(output) def assert_comment_links(response, comments, inline_comments): - response.mustcontain( - ''.format(comments)) - response.mustcontain( - ''.format(inline_comments)) - - - + response.mustcontain(''.format(comments)) + response.mustcontain(''.format(inline_comments)) diff --git a/rhodecode/apps/repository/tests/test_repo_commits.py b/rhodecode/apps/repository/tests/test_repo_commits.py index 67308e42..f6eda55b 100644 --- a/rhodecode/apps/repository/tests/test_repo_commits.py +++ b/rhodecode/apps/repository/tests/test_repo_commits.py @@ -25,14 +25,12 @@ from rhodecode.tests.routes import route_path @pytest.mark.usefixtures("app") class TestRepoCommitView(object): - def test_show_commit(self, backend): commit_id = self.commit_id[backend.alias] - response = self.app.get(route_path( - 'repo_commit', repo_name=backend.repo_name, commit_id=commit_id)) - response.mustcontain('Added a symlink') + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) + response.mustcontain("Added a symlink") response.mustcontain(commit_id) - response.mustcontain('No newline at end of file') + response.mustcontain("No newline at end of file") def test_show_raw(self, backend): commit_id = self.commit_id[backend.alias] @@ -40,15 +38,13 @@ class TestRepoCommitView(object): # and we use memoryview here as a wrapper, quick turn-off self.app.lint = False - response = self.app.get(route_path( - 'repo_commit_raw', - repo_name=backend.repo_name, commit_id=commit_id)) + response = self.app.get(route_path("repo_commit_raw", repo_name=backend.repo_name, commit_id=commit_id)) assert response.body == self.diffs[backend.alias] def test_show_raw_patch(self, backend): - response = self.app.get(route_path( - 'repo_commit_patch', repo_name=backend.repo_name, - commit_id=self.commit_id[backend.alias])) + response = self.app.get( + route_path("repo_commit_patch", repo_name=backend.repo_name, commit_id=self.commit_id[backend.alias]) + ) assert response.body == self.patches[backend.alias] def test_commit_download(self, backend): @@ -56,28 +52,25 @@ class TestRepoCommitView(object): # and we use memoryview here as a wrapper, quick turn-off self.app.lint = False - response = self.app.get(route_path( - 'repo_commit_download', - repo_name=backend.repo_name, - commit_id=self.commit_id[backend.alias])) + response = self.app.get( + route_path("repo_commit_download", repo_name=backend.repo_name, commit_id=self.commit_id[backend.alias]) + ) assert response.body == self.diffs[backend.alias] def test_single_commit_page_different_ops(self, backend): commit_id = { - 'hg': '603d6c72c46d953420c89d36372f08d9f305f5dd', - 'git': '03fa803d7e9fb14daa9a3089e0d1494eda75d986', - 'svn': '337', + "hg": "603d6c72c46d953420c89d36372f08d9f305f5dd", + "git": "03fa803d7e9fb14daa9a3089e0d1494eda75d986", + "svn": "337", } diff_stat = { - 'hg': (21, 943, 288), - 'git': (20, 941, 286), - 'svn': (21, 943, 288), + "hg": (21, 943, 288), + "git": (20, 941, 286), + "svn": (21, 943, 288), } commit_id = commit_id[backend.alias] - response = self.app.get(route_path( - 'repo_commit', - repo_name=backend.repo_name, commit_id=commit_id)) + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) response.mustcontain(_shorten_commit_id(commit_id)) @@ -86,35 +79,26 @@ class TestRepoCommitView(object): compare_page.contains_change_summary(*file_changes) # files op files - response.mustcontain('File not present at commit: %s' % - _shorten_commit_id(commit_id)) + response.mustcontain("File not present at commit: %s" % _shorten_commit_id(commit_id)) # svn uses a different filename - if backend.alias == 'svn': - response.mustcontain('new file 10644') + if backend.alias == "svn": + response.mustcontain("new file 10644") else: - response.mustcontain('new file 100644') - response.mustcontain('Changed theme to ADC theme') # commit msg + response.mustcontain("new file 100644") + response.mustcontain("Changed theme to ADC theme") # commit msg self._check_new_diff_menus(response, right_menu=True) def test_commit_range_page_different_ops(self, backend): commit_id_range = { - 'hg': ( - '25d7e49c18b159446cadfa506a5cf8ad1cb04067', - '603d6c72c46d953420c89d36372f08d9f305f5dd'), - 'git': ( - '6fc9270775aaf5544c1deb014f4ddd60c952fcbb', - '03fa803d7e9fb14daa9a3089e0d1494eda75d986'), - 'svn': ( - '335', - '337'), + "hg": ("25d7e49c18b159446cadfa506a5cf8ad1cb04067", "603d6c72c46d953420c89d36372f08d9f305f5dd"), + "git": ("6fc9270775aaf5544c1deb014f4ddd60c952fcbb", "03fa803d7e9fb14daa9a3089e0d1494eda75d986"), + "svn": ("335", "337"), } commit_ids = commit_id_range[backend.alias] - commit_id = '%s...%s' % (commit_ids[0], commit_ids[1]) - response = self.app.get(route_path( - 'repo_commit', - repo_name=backend.repo_name, commit_id=commit_id)) + commit_id = "%s...%s" % (commit_ids[0], commit_ids[1]) + response = self.app.get(route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id)) response.mustcontain(_shorten_commit_id(commit_ids[0])) response.mustcontain(_shorten_commit_id(commit_ids[1])) @@ -122,131 +106,117 @@ class TestRepoCommitView(object): compare_page = ComparePage(response) # svn is special - if backend.alias == 'svn': - response.mustcontain('new file 10644') + if backend.alias == "svn": + response.mustcontain("new file 10644") for file_changes in [(1, 5, 1), (12, 236, 22), (21, 943, 288)]: compare_page.contains_change_summary(*file_changes) - elif backend.alias == 'git': - response.mustcontain('new file 100644') + elif backend.alias == "git": + response.mustcontain("new file 100644") for file_changes in [(12, 222, 20), (20, 941, 286)]: compare_page.contains_change_summary(*file_changes) else: - response.mustcontain('new file 100644') + response.mustcontain("new file 100644") for file_changes in [(12, 222, 20), (21, 943, 288)]: compare_page.contains_change_summary(*file_changes) # files op files - response.mustcontain('File not present at commit: %s' % _shorten_commit_id(commit_ids[1])) - response.mustcontain('Added docstrings to vcs.cli') # commit msg - response.mustcontain('Changed theme to ADC theme') # commit msg + response.mustcontain("File not present at commit: %s" % _shorten_commit_id(commit_ids[1])) + response.mustcontain("Added docstrings to vcs.cli") # commit msg + response.mustcontain("Changed theme to ADC theme") # commit msg self._check_new_diff_menus(response) def test_combined_compare_commit_page_different_ops(self, backend): commit_id_range = { - 'hg': ( - '4fdd71e9427417b2e904e0464c634fdee85ec5a7', - '603d6c72c46d953420c89d36372f08d9f305f5dd'), - 'git': ( - 'f5fbf9cfd5f1f1be146f6d3b38bcd791a7480c13', - '03fa803d7e9fb14daa9a3089e0d1494eda75d986'), - 'svn': ( - '335', - '337'), + "hg": ("4fdd71e9427417b2e904e0464c634fdee85ec5a7", "603d6c72c46d953420c89d36372f08d9f305f5dd"), + "git": ("f5fbf9cfd5f1f1be146f6d3b38bcd791a7480c13", "03fa803d7e9fb14daa9a3089e0d1494eda75d986"), + "svn": ("335", "337"), } commit_ids = commit_id_range[backend.alias] - response = self.app.get(route_path( - 'repo_compare', - repo_name=backend.repo_name, - source_ref_type='rev', source_ref=commit_ids[0], - target_ref_type='rev', target_ref=commit_ids[1], )) + response = self.app.get( + route_path( + "repo_compare", + repo_name=backend.repo_name, + source_ref_type="rev", + source_ref=commit_ids[0], + target_ref_type="rev", + target_ref=commit_ids[1], + ) + ) response.mustcontain(_shorten_commit_id(commit_ids[0])) response.mustcontain(_shorten_commit_id(commit_ids[1])) # files op files - response.mustcontain('File not present at commit: %s' % - _shorten_commit_id(commit_ids[1])) + response.mustcontain("File not present at commit: %s" % _shorten_commit_id(commit_ids[1])) compare_page = ComparePage(response) # svn is special - if backend.alias == 'svn': - response.mustcontain('new file 10644') + if backend.alias == "svn": + response.mustcontain("new file 10644") file_changes = (32, 1179, 310) compare_page.contains_change_summary(*file_changes) - elif backend.alias == 'git': - response.mustcontain('new file 100644') + elif backend.alias == "git": + response.mustcontain("new file 100644") file_changes = (31, 1163, 306) compare_page.contains_change_summary(*file_changes) else: - response.mustcontain('new file 100644') + response.mustcontain("new file 100644") file_changes = (32, 1165, 308) compare_page.contains_change_summary(*file_changes) - response.mustcontain('Added docstrings to vcs.cli') # commit msg - response.mustcontain('Changed theme to ADC theme') # commit msg + response.mustcontain("Added docstrings to vcs.cli") # commit msg + response.mustcontain("Changed theme to ADC theme") # commit msg self._check_new_diff_menus(response) def test_changeset_range(self, backend): - self._check_changeset_range( - backend, self.commit_id_range, self.commit_id_range_result) + self._check_changeset_range(backend, self.commit_id_range, self.commit_id_range_result) def test_changeset_range_with_initial_commit(self, backend): commit_id_range = { - 'hg': ( - 'b986218ba1c9b0d6a259fac9b050b1724ed8e545' - '...6cba7170863a2411822803fa77a0a264f1310b35'), - 'git': ( - 'c1214f7e79e02fc37156ff215cd71275450cffc3' - '...fa6600f6848800641328adbf7811fd2372c02ab2'), - 'svn': '1...3', + "hg": ("b986218ba1c9b0d6a259fac9b050b1724ed8e545...6cba7170863a2411822803fa77a0a264f1310b35"), + "git": ("c1214f7e79e02fc37156ff215cd71275450cffc3...fa6600f6848800641328adbf7811fd2372c02ab2"), + "svn": "1...3", } commit_id_range_result = { - 'hg': ['b986218ba1c9', '3d8f361e72ab', '6cba7170863a'], - 'git': ['c1214f7e79e0', '38b5fe81f109', 'fa6600f68488'], - 'svn': ['1', '2', '3'], + "hg": ["b986218ba1c9", "3d8f361e72ab", "6cba7170863a"], + "git": ["c1214f7e79e0", "38b5fe81f109", "fa6600f68488"], + "svn": ["1", "2", "3"], } - self._check_changeset_range( - backend, commit_id_range, commit_id_range_result) + self._check_changeset_range(backend, commit_id_range, commit_id_range_result) - def _check_changeset_range( - self, backend, commit_id_ranges, commit_id_range_result): + def _check_changeset_range(self, backend, commit_id_ranges, commit_id_range_result): response = self.app.get( - route_path('repo_commit', - repo_name=backend.repo_name, - commit_id=commit_id_ranges[backend.alias])) + route_path("repo_commit", repo_name=backend.repo_name, commit_id=commit_id_ranges[backend.alias]) + ) expected_result = commit_id_range_result[backend.alias] - response.mustcontain('{} commits'.format(len(expected_result))) + response.mustcontain("{} commits".format(len(expected_result))) for commit_id in expected_result: response.mustcontain(commit_id) commit_id = { - 'hg': '2062ec7beeeaf9f44a1c25c41479565040b930b2', - 'svn': '393', - 'git': 'fd627b9e0dd80b47be81af07c4a98518244ed2f7', + "hg": "2062ec7beeeaf9f44a1c25c41479565040b930b2", + "svn": "393", + "git": "fd627b9e0dd80b47be81af07c4a98518244ed2f7", } commit_id_range = { - 'hg': ( - 'a53d9201d4bc278910d416d94941b7ea007ecd52' - '...2062ec7beeeaf9f44a1c25c41479565040b930b2'), - 'git': ( - '7ab37bc680b4aa72c34d07b230c866c28e9fc204' - '...fd627b9e0dd80b47be81af07c4a98518244ed2f7'), - 'svn': '391...393', + "hg": ("a53d9201d4bc278910d416d94941b7ea007ecd52...2062ec7beeeaf9f44a1c25c41479565040b930b2"), + "git": ("7ab37bc680b4aa72c34d07b230c866c28e9fc204...fd627b9e0dd80b47be81af07c4a98518244ed2f7"), + "svn": "391...393", } commit_id_range_result = { - 'hg': ['a53d9201d4bc', '96507bd11ecc', '2062ec7beeea'], - 'git': ['7ab37bc680b4', '5f2c6ee19592', 'fd627b9e0dd8'], - 'svn': ['391', '392', '393'], + "hg": ["a53d9201d4bc", "96507bd11ecc", "2062ec7beeea"], + "git": ["7ab37bc680b4", "5f2c6ee19592", "fd627b9e0dd8"], + "svn": ["391", "392", "393"], } diffs = { - 'hg': br"""diff --git a/README b/README + "hg": rb"""diff --git a/README b/README new file mode 120000 --- /dev/null +++ b/README @@ -254,7 +224,7 @@ new file mode 120000 +README.rst \ No newline at end of file """, - 'git': br"""diff --git a/README b/README + "git": rb"""diff --git a/README b/README new file mode 120000 index 0000000..92cacd2 --- /dev/null @@ -263,7 +233,7 @@ index 0000000..92cacd2 +README.rst \ No newline at end of file """, - 'svn': b"""Index: README + "svn": b"""Index: README =================================================================== diff --git a/README b/README new file mode 10644 @@ -276,7 +246,7 @@ new file mode 10644 } patches = { - 'hg': br"""# HG changeset patch + "hg": rb"""# HG changeset patch # User Marcin Kuzminski # Date 2014-01-07 12:21:40 # Node ID 2062ec7beeeaf9f44a1c25c41479565040b930b2 @@ -284,32 +254,38 @@ new file mode 10644 Added a symlink -""" + diffs['hg'], - 'git': br"""From fd627b9e0dd80b47be81af07c4a98518244ed2f7 2014-01-07 12:22:20 +""" + + diffs["hg"], + "git": rb"""From fd627b9e0dd80b47be81af07c4a98518244ed2f7 2014-01-07 12:22:20 From: Marcin Kuzminski Date: 2014-01-07 12:22:20 Subject: [PATCH] Added a symlink --- -""" + diffs['git'], - 'svn': br"""# SVN changeset patch +""" + + diffs["git"], + "svn": rb"""# SVN changeset patch # User marcin # Date 2014-09-02 12:25:22.071142 # Revision 393 Added a symlink -""" + diffs['svn'], +""" + + diffs["svn"], } - def _check_new_diff_menus(self, response, right_menu=False,): + def _check_new_diff_menus( + self, + response, + right_menu=False, + ): # individual file diff menus - for elem in ['Show file before', 'Show file after']: + for elem in ["Show file before", "Show file after"]: response.mustcontain(elem) # right pane diff menus if right_menu: - for elem in ['Hide whitespace changes', 'Toggle wide diff', - 'Show full context diff']: + for elem in ["Hide whitespace changes", "Toggle wide diff", "Show full context diff"]: response.mustcontain(elem) diff --git a/rhodecode/apps/repository/tests/test_repo_compare.py b/rhodecode/apps/repository/tests/test_repo_compare.py index 7319837c..4abce370 100644 --- a/rhodecode/apps/repository/tests/test_repo_compare.py +++ b/rhodecode/apps/repository/tests/test_repo_compare.py @@ -28,11 +28,9 @@ from rhodecode.tests.routes import route_path @pytest.mark.usefixtures("autologin_user", "app") class TestCompareView(object): - def test_compare_index_is_reached_at_least_once(self, backend): repo = backend.repo - self.app.get( - route_path('repo_compare_select', repo_name=repo.repo_name)) + self.app.get(route_path("repo_compare_select", repo_name=repo.repo_name)) @pytest.mark.xfail_backends("svn", reason="Requires pull") def test_compare_remote_with_different_commit_indexes(self, backend): @@ -56,47 +54,79 @@ class TestCompareView(object): # prepare fork commit0 = commit_change( - fork.repo_name, filename=b'file1', content=b'A', - message='A - Initial Commit', vcs_type=backend.alias, parent=None, newfile=True) + fork.repo_name, + filename=b"file1", + content=b"A", + message="A - Initial Commit", + vcs_type=backend.alias, + parent=None, + newfile=True, + ) commit1 = commit_change( - fork.repo_name, filename=b'file1', content=b'B', - message='B, child of A', vcs_type=backend.alias, parent=commit0) + fork.repo_name, + filename=b"file1", + content=b"B", + message="B, child of A", + vcs_type=backend.alias, + parent=commit0, + ) commit_change( # commit 2 - fork.repo_name, filename=b'file1', content=b'C', - message='C, child of B', vcs_type=backend.alias, parent=commit1) + fork.repo_name, + filename=b"file1", + content=b"C", + message="C, child of B", + vcs_type=backend.alias, + parent=commit1, + ) commit3 = commit_change( - fork.repo_name, filename=b'file1', content=b'D', - message='D, child of A', vcs_type=backend.alias, parent=commit0, branch='feature') + fork.repo_name, + filename=b"file1", + content=b"D", + message="D, child of A", + vcs_type=backend.alias, + parent=commit0, + branch="feature", + ) commit4 = commit_change( - fork.repo_name, filename=b'file1', content=b'E', - message='E, child of D', vcs_type=backend.alias, parent=commit3, branch='feature') + fork.repo_name, + filename=b"file1", + content=b"E", + message="E, child of D", + vcs_type=backend.alias, + parent=commit3, + branch="feature", + ) # prepare origin repository, taking just the history up to D origin_repo = origin.scm_instance(cache=False) - origin_repo.config.clear_section('hooks') + origin_repo.config.clear_section("hooks") origin_repo.pull(fork.repo_full_path, commit_ids=[commit3.raw_id]) origin_repo = origin.scm_instance(cache=False) # cache rebuild # Verify test fixture setup # This does not work for git - if backend.alias != 'git': + if backend.alias != "git": assert 5 == len(fork.scm_instance(cache=False).commit_ids) assert 2 == len(origin_repo.commit_ids) # Comparing the revisions response = self.app.get( - route_path('repo_compare', - repo_name=origin.repo_name, - source_ref_type="rev", source_ref=commit3.raw_id, - target_ref_type="rev", target_ref=commit4.raw_id, - params=dict(merge='1', target_repo=fork.repo_name) - ), - status=200) + route_path( + "repo_compare", + repo_name=origin.repo_name, + source_ref_type="rev", + source_ref=commit3.raw_id, + target_ref_type="rev", + target_ref=commit4.raw_id, + params=dict(merge="1", target_repo=fork.repo_name), + ), + status=200, + ) compare_page = ComparePage(response) compare_page.contains_commits([commit4]) @@ -107,42 +137,65 @@ class TestCompareView(object): # commit something ! commit0 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\n', - message='commit1', vcs_type=backend.alias, parent=None, - newfile=True) + repo1.repo_name, + filename=b"file1", + content=b"line1\n", + message="commit1", + vcs_type=backend.alias, + parent=None, + newfile=True, + ) # fork this repo repo2 = backend.create_fork() # add two extra commit into fork commit1 = commit_change( - repo2.repo_name, filename=b'file1', content=b'line1\nline2\n', - message='commit2', vcs_type=backend.alias, parent=commit0) + repo2.repo_name, + filename=b"file1", + content=b"line1\nline2\n", + message="commit2", + vcs_type=backend.alias, + parent=commit0, + ) commit2 = commit_change( - repo2.repo_name, filename=b'file1', content=b'line1\nline2\nline3\n', - message='commit3', vcs_type=backend.alias, parent=commit1) + repo2.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\n", + message="commit3", + vcs_type=backend.alias, + parent=commit1, + ) commit_id1 = repo1.scm_instance().DEFAULT_BRANCH_NAME commit_id2 = repo2.scm_instance().DEFAULT_BRANCH_NAME response = self.app.get( - route_path('repo_compare', - repo_name=repo1.repo_name, - source_ref_type="branch", source_ref=commit_id2, - target_ref_type="branch", target_ref=commit_id1, - params=dict(merge='1', target_repo=repo2.repo_name) - )) + route_path( + "repo_compare", + repo_name=repo1.repo_name, + source_ref_type="branch", + source_ref=commit_id2, + target_ref_type="branch", + target_ref=commit_id1, + params=dict(merge="1", target_repo=repo2.repo_name), + ) + ) - response.mustcontain('%s@%s' % (repo1.repo_name, commit_id2)) - response.mustcontain('%s@%s' % (repo2.repo_name, commit_id1)) + response.mustcontain("%s@%s" % (repo1.repo_name, commit_id2)) + response.mustcontain("%s@%s" % (repo2.repo_name, commit_id1)) compare_page = ComparePage(response) compare_page.contains_change_summary(1, 2, 0) compare_page.contains_commits([commit1, commit2]) - anchor = 'a_c-{}-826e8142e6ba'.format(commit0.short_id) - compare_page.contains_file_links_and_anchors([('file1', anchor), ]) + anchor = "a_c-{}-826e8142e6ba".format(commit0.short_id) + compare_page.contains_file_links_and_anchors( + [ + ("file1", anchor), + ] + ) # Swap is removed when comparing branches since it's a PR feature and # it is then a preview mode @@ -155,47 +208,75 @@ class TestCompareView(object): # commit something ! commit0 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\n', - message='commit1', vcs_type=backend.alias, parent=None, - newfile=True) + repo1.repo_name, + filename=b"file1", + content=b"line1\n", + message="commit1", + vcs_type=backend.alias, + parent=None, + newfile=True, + ) # fork this repo repo2 = backend.create_fork() # now commit something to origin repo commit_change( - repo1.repo_name, filename=b'file2', content=b'line1file2\n', - message='commit2', vcs_type=backend.alias, parent=commit0, - newfile=True) + repo1.repo_name, + filename=b"file2", + content=b"line1file2\n", + message="commit2", + vcs_type=backend.alias, + parent=commit0, + newfile=True, + ) # add two extra commit into fork commit1 = commit_change( - repo2.repo_name, filename=b'file1', content=b'line1\nline2\n', - message='commit2', vcs_type=backend.alias, parent=commit0) + repo2.repo_name, + filename=b"file1", + content=b"line1\nline2\n", + message="commit2", + vcs_type=backend.alias, + parent=commit0, + ) commit2 = commit_change( - repo2.repo_name, filename=b'file1', content=b'line1\nline2\nline3\n', - message='commit3', vcs_type=backend.alias, parent=commit1) + repo2.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\n", + message="commit3", + vcs_type=backend.alias, + parent=commit1, + ) commit_id1 = repo1.scm_instance().DEFAULT_BRANCH_NAME commit_id2 = repo2.scm_instance().DEFAULT_BRANCH_NAME response = self.app.get( - route_path('repo_compare', - repo_name=repo1.repo_name, - source_ref_type="branch", source_ref=commit_id2, - target_ref_type="branch", target_ref=commit_id1, - params=dict(merge='1', target_repo=repo2.repo_name), - )) + route_path( + "repo_compare", + repo_name=repo1.repo_name, + source_ref_type="branch", + source_ref=commit_id2, + target_ref_type="branch", + target_ref=commit_id1, + params=dict(merge="1", target_repo=repo2.repo_name), + ) + ) - response.mustcontain(f'{repo1.repo_name}@{commit_id2}') - response.mustcontain(f'{repo2.repo_name}@{commit_id1}') + response.mustcontain(f"{repo1.repo_name}@{commit_id2}") + response.mustcontain(f"{repo2.repo_name}@{commit_id1}") compare_page = ComparePage(response) compare_page.contains_change_summary(1, 2, 0) compare_page.contains_commits([commit1, commit2]) - anchor = f'a_c-{commit0.short_id}-826e8142e6ba' - compare_page.contains_file_links_and_anchors([('file1', anchor), ]) + anchor = f"a_c-{commit0.short_id}-826e8142e6ba" + compare_page.contains_file_links_and_anchors( + [ + ("file1", anchor), + ] + ) # Swap is removed when comparing branches since it's a PR feature and # it is then a preview mode @@ -209,19 +290,22 @@ class TestCompareView(object): fork = backend.create_repo(number_of_commits=1) response = self.app.get( - route_path('repo_compare', - repo_name=orig.repo_name, - source_ref_type="rev", source_ref="tip", - target_ref_type="rev", target_ref="tip", - params=dict(merge='1', target_repo=fork.repo_name), - ), - status=302) + route_path( + "repo_compare", + repo_name=orig.repo_name, + source_ref_type="rev", + source_ref="tip", + target_ref_type="rev", + target_ref="tip", + params=dict(merge="1", target_repo=fork.repo_name), + ), + status=302, + ) response = response.follow() response.mustcontain("Repositories unrelated.") @pytest.mark.xfail_backends("svn") def test_compare_cherry_pick_commits_from_bottom(self, backend): - # repo1: # commit0: # commit1: @@ -238,47 +322,85 @@ class TestCompareView(object): # commit something ! commit0 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\n', - message='commit1', vcs_type=backend.alias, parent=None, - newfile=True) + repo1.repo_name, + filename=b"file1", + content=b"line1\n", + message="commit1", + vcs_type=backend.alias, + parent=None, + newfile=True, + ) commit1 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\nline2\n', - message='commit2', vcs_type=backend.alias, parent=commit0) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\n", + message="commit2", + vcs_type=backend.alias, + parent=commit0, + ) # fork this repo repo2 = backend.create_fork() # now make commit3-6 commit2 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\nline2\nline3\n', - message='commit3', vcs_type=backend.alias, parent=commit1) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\n", + message="commit3", + vcs_type=backend.alias, + parent=commit1, + ) commit3 = commit_change( - repo1.repo_name, filename=b'file1',content=b'line1\nline2\nline3\nline4\n', - message='commit4', vcs_type=backend.alias, parent=commit2) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\nline4\n", + message="commit4", + vcs_type=backend.alias, + parent=commit2, + ) commit4 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\nline2\nline3\nline4\nline5\n', - message='commit5', vcs_type=backend.alias, parent=commit3) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\nline4\nline5\n", + message="commit5", + vcs_type=backend.alias, + parent=commit3, + ) commit_change( # commit 5 - repo1.repo_name, filename=b'file1', content=b'line1\nline2\nline3\nline4\nline5\nline6\n', - message='commit6', vcs_type=backend.alias, parent=commit4) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\nline4\nline5\nline6\n", + message="commit6", + vcs_type=backend.alias, + parent=commit4, + ) response = self.app.get( - route_path('repo_compare', - repo_name=repo2.repo_name, - # parent of commit2, in target repo2 - source_ref_type="rev", source_ref=commit1.raw_id, - target_ref_type="rev", target_ref=commit4.raw_id, - params=dict(merge='1', target_repo=repo1.repo_name), - )) - response.mustcontain('%s@%s' % (repo2.repo_name, commit1.short_id)) - response.mustcontain('%s@%s' % (repo1.repo_name, commit4.short_id)) + route_path( + "repo_compare", + repo_name=repo2.repo_name, + # parent of commit2, in target repo2 + source_ref_type="rev", + source_ref=commit1.raw_id, + target_ref_type="rev", + target_ref=commit4.raw_id, + params=dict(merge="1", target_repo=repo1.repo_name), + ) + ) + response.mustcontain("%s@%s" % (repo2.repo_name, commit1.short_id)) + response.mustcontain("%s@%s" % (repo1.repo_name, commit4.short_id)) # files compare_page = ComparePage(response) compare_page.contains_change_summary(1, 3, 0) compare_page.contains_commits([commit2, commit3, commit4]) - anchor = 'a_c-{}-826e8142e6ba'.format(commit1.short_id) - compare_page.contains_file_links_and_anchors([('file1', anchor),]) + anchor = "a_c-{}-826e8142e6ba".format(commit1.short_id) + compare_page.contains_file_links_and_anchors( + [ + ("file1", anchor), + ] + ) @pytest.mark.xfail_backends("svn") def test_compare_cherry_pick_commits_from_top(self, backend): @@ -298,51 +420,87 @@ class TestCompareView(object): # commit something ! commit0 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\n', - message='commit1', vcs_type=backend.alias, parent=None, - newfile=True) + repo1.repo_name, + filename=b"file1", + content=b"line1\n", + message="commit1", + vcs_type=backend.alias, + parent=None, + newfile=True, + ) commit1 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\nline2\n', - message='commit2', vcs_type=backend.alias, parent=commit0) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\n", + message="commit2", + vcs_type=backend.alias, + parent=commit0, + ) # fork this repo backend.create_fork() # now make commit3-6 commit2 = commit_change( - repo1.repo_name, filename=b'file1', content=b'line1\nline2\nline3\n', - message='commit3', vcs_type=backend.alias, parent=commit1) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\n", + message="commit3", + vcs_type=backend.alias, + parent=commit1, + ) commit3 = commit_change( - repo1.repo_name, filename=b'file1', - content=b'line1\nline2\nline3\nline4\n', message='commit4', - vcs_type=backend.alias, parent=commit2) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\nline4\n", + message="commit4", + vcs_type=backend.alias, + parent=commit2, + ) commit4 = commit_change( - repo1.repo_name, filename=b'file1', - content=b'line1\nline2\nline3\nline4\nline5\n', message='commit5', - vcs_type=backend.alias, parent=commit3) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\nline4\nline5\n", + message="commit5", + vcs_type=backend.alias, + parent=commit3, + ) commit5 = commit_change( - repo1.repo_name, filename=b'file1', - content=b'line1\nline2\nline3\nline4\nline5\nline6\n', - message='commit6', vcs_type=backend.alias, parent=commit4) + repo1.repo_name, + filename=b"file1", + content=b"line1\nline2\nline3\nline4\nline5\nline6\n", + message="commit6", + vcs_type=backend.alias, + parent=commit4, + ) response = self.app.get( - route_path('repo_compare', - repo_name=repo1.repo_name, - # parent of commit3, not in source repo2 - source_ref_type="rev", source_ref=commit2.raw_id, - target_ref_type="rev", target_ref=commit5.raw_id, - params=dict(merge='1'),)) + route_path( + "repo_compare", + repo_name=repo1.repo_name, + # parent of commit3, not in source repo2 + source_ref_type="rev", + source_ref=commit2.raw_id, + target_ref_type="rev", + target_ref=commit5.raw_id, + params=dict(merge="1"), + ) + ) - response.mustcontain('%s@%s' % (repo1.repo_name, commit2.short_id)) - response.mustcontain('%s@%s' % (repo1.repo_name, commit5.short_id)) + response.mustcontain("%s@%s" % (repo1.repo_name, commit2.short_id)) + response.mustcontain("%s@%s" % (repo1.repo_name, commit5.short_id)) compare_page = ComparePage(response) compare_page.contains_change_summary(1, 3, 0) compare_page.contains_commits([commit3, commit4, commit5]) # files - anchor = 'a_c-{}-826e8142e6ba'.format(commit2.short_id) - compare_page.contains_file_links_and_anchors([('file1', anchor),]) + anchor = "a_c-{}-826e8142e6ba".format(commit2.short_id) + compare_page.contains_file_links_and_anchors( + [ + ("file1", anchor), + ] + ) @pytest.mark.xfail_backends("svn") def test_compare_remote_branches(self, backend): @@ -355,28 +513,33 @@ class TestCompareView(object): commit_id2_short = repo1.get_commit(commit_idx=6).short_id response = self.app.get( - route_path('repo_compare', - repo_name=repo1.repo_name, - source_ref_type="rev", source_ref=commit_id1, - target_ref_type="rev", target_ref=commit_id2, - params=dict(merge='1', target_repo=repo2.repo_name), - )) + route_path( + "repo_compare", + repo_name=repo1.repo_name, + source_ref_type="rev", + source_ref=commit_id1, + target_ref_type="rev", + target_ref=commit_id2, + params=dict(merge="1", target_repo=repo2.repo_name), + ) + ) - response.mustcontain('%s@%s' % (repo1.repo_name, commit_id1)) - response.mustcontain('%s@%s' % (repo2.repo_name, commit_id2)) + response.mustcontain("%s@%s" % (repo1.repo_name, commit_id1)) + response.mustcontain("%s@%s" % (repo2.repo_name, commit_id2)) compare_page = ComparePage(response) # outgoing commits between those commits - compare_page.contains_commits( - [repo2.get_commit(commit_idx=x) for x in [4, 5, 6]]) + compare_page.contains_commits([repo2.get_commit(commit_idx=x) for x in [4, 5, 6]]) # files - compare_page.contains_file_links_and_anchors([ - ('vcs/backends/hg.py', 'a_c-{}-9c390eb52cd6'.format(commit_id2_short)), - ('vcs/backends/__init__.py', 'a_c-{}-41b41c1f2796'.format(commit_id1_short)), - ('vcs/backends/base.py', 'a_c-{}-2f574d260608'.format(commit_id1_short)), - ]) + compare_page.contains_file_links_and_anchors( + [ + ("vcs/backends/hg.py", "a_c-{}-9c390eb52cd6".format(commit_id2_short)), + ("vcs/backends/__init__.py", "a_c-{}-41b41c1f2796".format(commit_id1_short)), + ("vcs/backends/base.py", "a_c-{}-2f574d260608".format(commit_id1_short)), + ] + ) @pytest.mark.xfail_backends("svn") def test_source_repo_new_commits_after_forking_simple_diff(self, backend): @@ -384,9 +547,8 @@ class TestCompareView(object): r1_name = repo1.repo_name commit0 = commit_change( - repo=r1_name, filename=b'file1', - content=b'line1', message='commit1', vcs_type=backend.alias, - newfile=True) + repo=r1_name, filename=b"file1", content=b"line1", message="commit1", vcs_type=backend.alias, newfile=True + ) assert repo1.scm_instance().commit_ids == [commit0.raw_id] # fork the repo1 @@ -397,55 +559,81 @@ class TestCompareView(object): r2_name = repo2.repo_name commit1 = commit_change( - repo=r2_name, filename=b'file1-fork', - content=b'file1-line1-from-fork', message='commit1-fork', - vcs_type=backend.alias, parent=repo2.scm_instance()[-1], - newfile=True) + repo=r2_name, + filename=b"file1-fork", + content=b"file1-line1-from-fork", + message="commit1-fork", + vcs_type=backend.alias, + parent=repo2.scm_instance()[-1], + newfile=True, + ) commit2 = commit_change( - repo=r2_name, filename=b'file2-fork', - content=b'file2-line1-from-fork', message='commit2-fork', - vcs_type=backend.alias, parent=commit1, - newfile=True) + repo=r2_name, + filename=b"file2-fork", + content=b"file2-line1-from-fork", + message="commit2-fork", + vcs_type=backend.alias, + parent=commit1, + newfile=True, + ) commit_change( # commit 3 - repo=r2_name, filename=b'file3-fork', - content=b'file3-line1-from-fork', message='commit3-fork', - vcs_type=backend.alias, parent=commit2, newfile=True) + repo=r2_name, + filename=b"file3-fork", + content=b"file3-line1-from-fork", + message="commit3-fork", + vcs_type=backend.alias, + parent=commit2, + newfile=True, + ) # compare ! commit_id1 = repo1.scm_instance().DEFAULT_BRANCH_NAME commit_id2 = repo2.scm_instance().DEFAULT_BRANCH_NAME response = self.app.get( - route_path('repo_compare', - repo_name=r2_name, - source_ref_type="branch", source_ref=commit_id1, - target_ref_type="branch", target_ref=commit_id2, - params=dict(merge='1', target_repo=r1_name), - )) + route_path( + "repo_compare", + repo_name=r2_name, + source_ref_type="branch", + source_ref=commit_id1, + target_ref_type="branch", + target_ref=commit_id2, + params=dict(merge="1", target_repo=r1_name), + ) + ) - response.mustcontain('%s@%s' % (r2_name, commit_id1)) - response.mustcontain('%s@%s' % (r1_name, commit_id2)) - response.mustcontain('No files') - response.mustcontain('No commits in this compare') + response.mustcontain("%s@%s" % (r2_name, commit_id1)) + response.mustcontain("%s@%s" % (r1_name, commit_id2)) + response.mustcontain("No files") + response.mustcontain("No commits in this compare") commit0 = commit_change( - repo=r1_name, filename=b'file2', - content=b'line1-added-after-fork', message='commit2-parent', - vcs_type=backend.alias, parent=None, newfile=True) + repo=r1_name, + filename=b"file2", + content=b"line1-added-after-fork", + message="commit2-parent", + vcs_type=backend.alias, + parent=None, + newfile=True, + ) # compare ! response = self.app.get( - route_path('repo_compare', - repo_name=r2_name, - source_ref_type="branch", source_ref=commit_id1, - target_ref_type="branch", target_ref=commit_id2, - params=dict(merge='1', target_repo=r1_name), - )) + route_path( + "repo_compare", + repo_name=r2_name, + source_ref_type="branch", + source_ref=commit_id1, + target_ref_type="branch", + target_ref=commit_id2, + params=dict(merge="1", target_repo=r1_name), + ) + ) - response.mustcontain('%s@%s' % (r2_name, commit_id1)) - response.mustcontain('%s@%s' % (r1_name, commit_id2)) + response.mustcontain("%s@%s" % (r2_name, commit_id1)) + response.mustcontain("%s@%s" % (r1_name, commit_id2)) response.mustcontain("""commit2-parent""") response.mustcontain("""line1-added-after-fork""") @@ -458,13 +646,17 @@ class TestCompareView(object): commit1 = backend.repo.get_commit(commit_idx=1) response = self.app.get( - route_path('repo_compare', - repo_name=backend.repo_name, - source_ref_type="rev", source_ref=commit0.raw_id, - target_ref_type="rev", target_ref=commit1.raw_id, - params=dict(merge='1') - ), - extra_environ=xhr_header, ) + route_path( + "repo_compare", + repo_name=backend.repo_name, + source_ref_type="rev", + source_ref=commit0.raw_id, + target_ref_type="rev", + target_ref=commit1.raw_id, + params=dict(merge="1"), + ), + extra_environ=xhr_header, + ) # outgoing commits between those commits compare_page = ComparePage(response) @@ -474,40 +666,51 @@ class TestCompareView(object): repo = backend.repo self.app.get( - route_path('repo_compare', - repo_name='badrepo', - source_ref_type="rev", source_ref='tip', - target_ref_type="rev", target_ref='tip', - params=dict(merge='1', target_repo=repo.repo_name) - ), - status=404) + route_path( + "repo_compare", + repo_name="badrepo", + source_ref_type="rev", + source_ref="tip", + target_ref_type="rev", + target_ref="tip", + params=dict(merge="1", target_repo=repo.repo_name), + ), + status=404, + ) def test_errors_when_comparing_unknown_target_repo(self, backend): repo = backend.repo - badrepo = 'badrepo' + badrepo = "badrepo" response = self.app.get( - route_path('repo_compare', - repo_name=repo.repo_name, - source_ref_type="rev", source_ref='tip', - target_ref_type="rev", target_ref='tip', - params=dict(merge='1', target_repo=badrepo), - ), - status=302) + route_path( + "repo_compare", + repo_name=repo.repo_name, + source_ref_type="rev", + source_ref="tip", + target_ref_type="rev", + target_ref="tip", + params=dict(merge="1", target_repo=badrepo), + ), + status=302, + ) redirected = response.follow() - redirected.mustcontain( - 'Could not find the target repo: `{}`'.format(badrepo)) + redirected.mustcontain("Could not find the target repo: `{}`".format(badrepo)) def test_compare_not_in_preview_mode(self, backend_stub): commit0 = backend_stub.repo.get_commit(commit_idx=0) commit1 = backend_stub.repo.get_commit(commit_idx=1) response = self.app.get( - route_path('repo_compare', - repo_name=backend_stub.repo_name, - source_ref_type="rev", source_ref=commit0.raw_id, - target_ref_type="rev", target_ref=commit1.raw_id, - )) + route_path( + "repo_compare", + repo_name=backend_stub.repo_name, + source_ref_type="rev", + source_ref=commit0.raw_id, + target_ref_type="rev", + target_ref=commit1.raw_id, + ) + ) # outgoing commits between those commits compare_page = ComparePage(response) @@ -518,75 +721,77 @@ class TestCompareView(object): orig = backend_hg.create_repo(number_of_commits=1) fork = backend_hg.create_fork() - settings_util.create_repo_rhodecode_ui( - orig, 'extensions', value='', key='largefiles', active=False) - settings_util.create_repo_rhodecode_ui( - fork, 'extensions', value='', key='largefiles', active=True) + settings_util.create_repo_rhodecode_ui(orig, "extensions", value="", key="largefiles", active=False) + settings_util.create_repo_rhodecode_ui(fork, "extensions", value="", key="largefiles", active=True) - compare_module = ('rhodecode.lib.vcs.backends.hg.repository.' - 'MercurialRepository.compare') + compare_module = "rhodecode.lib.vcs.backends.hg.repository.MercurialRepository.compare" with mock.patch(compare_module) as compare_mock: compare_mock.side_effect = RepositoryRequirementError() response = self.app.get( - route_path('repo_compare', - repo_name=orig.repo_name, - source_ref_type="rev", source_ref="tip", - target_ref_type="rev", target_ref="tip", - params=dict(merge='1', target_repo=fork.repo_name), - ), - status=302) + route_path( + "repo_compare", + repo_name=orig.repo_name, + source_ref_type="rev", + source_ref="tip", + target_ref_type="rev", + target_ref="tip", + params=dict(merge="1", target_repo=fork.repo_name), + ), + status=302, + ) - assert_session_flash( - response, - 'Could not compare repos with different large file settings') + assert_session_flash(response, "Could not compare repos with different large file settings") @pytest.mark.usefixtures("autologin_user") class TestCompareControllerSvn(object): - def test_supports_references_with_path(self, app, backend_svn): - repo = backend_svn['svn-simple-layout'] + repo = backend_svn["svn-simple-layout"] commit_id = repo.get_commit(commit_idx=-1).raw_id response = app.get( - route_path('repo_compare', - repo_name=repo.repo_name, - source_ref_type="tag", - source_ref="%s@%s" % ('tags/v0.1', commit_id), - target_ref_type="tag", - target_ref="%s@%s" % ('tags/v0.2', commit_id), - params=dict(merge='1'), - ), - status=200) + route_path( + "repo_compare", + repo_name=repo.repo_name, + source_ref_type="tag", + source_ref="%s@%s" % ("tags/v0.1", commit_id), + target_ref_type="tag", + target_ref="%s@%s" % ("tags/v0.2", commit_id), + params=dict(merge="1"), + ), + status=200, + ) # Expecting no commits, since both paths are at the same revision - response.mustcontain('No commits in this compare') + response.mustcontain("No commits in this compare") # Should find only one file changed when comparing those two tags - response.mustcontain('example.py') + response.mustcontain("example.py") compare_page = ComparePage(response) compare_page.contains_change_summary(1, 5, 1) def test_shows_commits_if_different_ids(self, app, backend_svn): - repo = backend_svn['svn-simple-layout'] + repo = backend_svn["svn-simple-layout"] source_id = repo.get_commit(commit_idx=-6).raw_id target_id = repo.get_commit(commit_idx=-1).raw_id response = app.get( - route_path('repo_compare', - repo_name=repo.repo_name, - source_ref_type="tag", - source_ref="%s@%s" % ('tags/v0.1', source_id), - target_ref_type="tag", - target_ref="%s@%s" % ('tags/v0.2', target_id), - params=dict(merge='1') - ), - status=200) + route_path( + "repo_compare", + repo_name=repo.repo_name, + source_ref_type="tag", + source_ref="%s@%s" % ("tags/v0.1", source_id), + target_ref_type="tag", + target_ref="%s@%s" % ("tags/v0.2", target_id), + params=dict(merge="1"), + ), + status=200, + ) # It should show commits - assert 'No commits in this compare' not in response.text + assert "No commits in this compare" not in response.text # Should find only one file changed when comparing those two tags - response.mustcontain('example.py') + response.mustcontain("example.py") compare_page = ComparePage(response) compare_page.contains_change_summary(1, 5, 1) @@ -602,22 +807,23 @@ class ComparePage(AssertResponse): self.contains_one_anchor(file_id) diffblock = doc.cssselect('[data-f-path="%s"]' % filename) assert len(diffblock) == 2 - for lnk in diffblock[0].cssselect('a'): - if 'permalink' in lnk.text: - assert '#{}'.format(file_id) in lnk.attrib['href'] + for lnk in diffblock[0].cssselect("a"): + if "permalink" in lnk.text: + assert "#{}".format(file_id) in lnk.attrib["href"] break else: - pytest.fail('Unable to find permalink') + pytest.fail("Unable to find permalink") def contains_change_summary(self, files_changed, inserted, deleted): template = ( - '{files_changed} file{plural} changed: ' - '{inserted} inserted, {deleted} deleted') - self.response.mustcontain(template.format( - files_changed=files_changed, - plural="s" if files_changed > 1 else "", - inserted=inserted, - deleted=deleted)) + "{files_changed} file{plural} changed: " + '{inserted} inserted, {deleted} deleted' + ) + self.response.mustcontain( + template.format( + files_changed=files_changed, plural="s" if files_changed > 1 else "", inserted=inserted, deleted=deleted + ) + ) def contains_commits(self, commits, ancestors=None): response = self.response @@ -625,19 +831,16 @@ class ComparePage(AssertResponse): for commit in commits: # Expecting to see the commit message in an element which # has the ID "c-{commit.raw_id}" - self.element_contains('#c-' + commit.raw_id, commit.message) - self.contains_one_link( - 'r%s:%s' % (commit.idx, commit.short_id), - self._commit_url(commit)) + self.element_contains("#c-" + commit.raw_id, commit.message) + self.contains_one_link("r%s:%s" % (commit.idx, commit.short_id), self._commit_url(commit)) if ancestors: - response.mustcontain('Ancestor') + response.mustcontain("Ancestor") for ancestor in ancestors: - self.contains_one_link( - ancestor.short_id, self._commit_url(ancestor)) + self.contains_one_link(ancestor.short_id, self._commit_url(ancestor)) def _commit_url(self, commit): - return '/%s/changeset/%s' % (commit.repository.name, commit.raw_id) + return "/%s/changeset/%s" % (commit.repository.name, commit.raw_id) def swap_is_hidden(self): assert '
%s""" % (fork_name, fork_name) + assert response.json["data"][0]["fork_name"] == """%s""" % (fork_name, fork_name) # remove this fork fixture.destroy_repo(fork_name) def test_fork_create(self, autologin_user, backend, csrf_token): fork_name = FORK_NAME[backend.alias] - description = 'fork of vcs test' + description = "fork of vcs test" repo_name = backend.repo_name source_repo = Repository.get_by_repo_name(repo_name) creation_args = { - 'repo_name': fork_name, - 'repo_group': '', - 'fork_parent_id': source_repo.repo_id, - 'repo_type': backend.alias, - 'description': description, - 'private': 'False', - 'csrf_token': csrf_token, + "repo_name": fork_name, + "repo_group": "", + "fork_parent_id": source_repo.repo_id, + "repo_type": backend.alias, + "description": description, + "private": "False", + "csrf_token": csrf_token, } - self.app.post( - route_path('repo_fork_create', repo_name=repo_name), creation_args) + self.app.post(route_path("repo_fork_create", repo_name=repo_name), creation_args) repo = Repository.get_by_repo_name(FORK_NAME[backend.alias]) assert repo.fork.repo_name == backend.repo_name # run the check page that triggers the flash message - response = self.app.get( - route_path('repo_creating_check', repo_name=fork_name)) + response = self.app.get(route_path("repo_creating_check", repo_name=fork_name)) # test if we have a message that fork is ok - assert_session_flash(response, - 'Forked repository %s as %s' % ( - repo_name, fork_name, fork_name)) + assert_session_flash( + response, 'Forked repository %s as %s' % (repo_name, fork_name, fork_name) + ) # test if the fork was created in the database - fork_repo = Session().query(Repository)\ - .filter(Repository.repo_name == fork_name).one() + fork_repo = Session().query(Repository).filter(Repository.repo_name == fork_name).one() assert fork_repo.repo_name == fork_name assert fork_repo.fork.repo_name == repo_name # test if the repository is visible in the list ? - response = self.app.get( - h.route_path('repo_summary', repo_name=fork_name)) + response = self.app.get(h.route_path("repo_summary", repo_name=fork_name)) response.mustcontain(fork_name) response.mustcontain(backend.alias) - response.mustcontain('Fork of') + response.mustcontain("Fork of") response.mustcontain('%s' % (repo_name, repo_name)) def test_fork_create_into_group(self, autologin_user, backend, csrf_token): - group = fixture.create_repo_group('vc') + group = fixture.create_repo_group("vc") group_id = group.group_id fork_name = FORK_NAME[backend.alias] - fork_name_full = 'vc/%s' % fork_name - description = 'fork of vcs test' + fork_name_full = "vc/%s" % fork_name + description = "fork of vcs test" repo_name = backend.repo_name source_repo = Repository.get_by_repo_name(repo_name) creation_args = { - 'repo_name': fork_name, - 'repo_group': group_id, - 'fork_parent_id': source_repo.repo_id, - 'repo_type': backend.alias, - 'description': description, - 'private': 'False', - 'csrf_token': csrf_token, + "repo_name": fork_name, + "repo_group": group_id, + "fork_parent_id": source_repo.repo_id, + "repo_type": backend.alias, + "description": description, + "private": "False", + "csrf_token": csrf_token, } - self.app.post( - route_path('repo_fork_create', repo_name=repo_name), creation_args) + self.app.post(route_path("repo_fork_create", repo_name=repo_name), creation_args) repo = Repository.get_by_repo_name(fork_name_full) assert repo.fork.repo_name == backend.repo_name # run the check page that triggers the flash message - response = self.app.get( - route_path('repo_creating_check', repo_name=fork_name_full)) + response = self.app.get(route_path("repo_creating_check", repo_name=fork_name_full)) # test if we have a message that fork is ok - assert_session_flash(response, - 'Forked repository %s as %s' % ( - repo_name, fork_name_full, fork_name_full)) + assert_session_flash( + response, 'Forked repository %s as %s' % (repo_name, fork_name_full, fork_name_full) + ) # test if the fork was created in the database - fork_repo = Session().query(Repository)\ - .filter(Repository.repo_name == fork_name_full).one() + fork_repo = Session().query(Repository).filter(Repository.repo_name == fork_name_full).one() assert fork_repo.repo_name == fork_name_full assert fork_repo.fork.repo_name == repo_name # test if the repository is visible in the list ? - response = self.app.get( - h.route_path('repo_summary', repo_name=fork_name_full)) + response = self.app.get(h.route_path("repo_summary", repo_name=fork_name_full)) response.mustcontain(fork_name_full) response.mustcontain(backend.alias) - response.mustcontain('Fork of') + response.mustcontain("Fork of") response.mustcontain('%s' % (repo_name, repo_name)) fixture.destroy_repo(fork_name_full) fixture.destroy_repo_group(group_id) def test_fork_read_permission(self, backend, xhr_header, user_util): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") user_id = user.user_id - self.log_user(user.username, 'qweqwe') + self.log_user(user.username, "qweqwe") # create a fake fork fork = user_util.create_repo(repo_type=backend.alias) @@ -234,27 +207,26 @@ class TestRepoForkViewTests(TestController): fork_name = fork.repo_name Session().commit() - forks = Repository.query()\ - .filter(Repository.repo_type == backend.alias)\ - .filter(Repository.fork_id == source.repo_id).all() + forks = ( + Repository.query() + .filter(Repository.repo_type == backend.alias) + .filter(Repository.fork_id == source.repo_id) + .all() + ) assert 1 == len(forks) # set read permissions for this - RepoModel().grant_user_permission( - repo=forks[0], user=user_id, perm='repository.read') + RepoModel().grant_user_permission(repo=forks[0], user=user_id, perm="repository.read") Session().commit() - response = self.app.get( - route_path('repo_forks_data', repo_name=repo_name), - extra_environ=xhr_header) + response = self.app.get(route_path("repo_forks_data", repo_name=repo_name), extra_environ=xhr_header) - assert response.json['data'][0]['fork_name'] == \ - """%s""" % (fork_name, fork_name) + assert response.json["data"][0]["fork_name"] == """%s""" % (fork_name, fork_name) def test_fork_none_permission(self, backend, xhr_header, user_util): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") user_id = user.user_id - self.log_user(user.username, 'qweqwe') + self.log_user(user.username, "qweqwe") # create a fake fork fork = user_util.create_repo(repo_type=backend.alias) @@ -265,31 +237,27 @@ class TestRepoForkViewTests(TestController): Session().commit() - forks = Repository.query()\ - .filter(Repository.repo_type == backend.alias)\ - .filter(Repository.fork_id == source.repo_id).all() + forks = ( + Repository.query() + .filter(Repository.repo_type == backend.alias) + .filter(Repository.fork_id == source.repo_id) + .all() + ) assert 1 == len(forks) # set none - RepoModel().grant_user_permission( - repo=forks[0], user=user_id, perm='repository.none') + RepoModel().grant_user_permission(repo=forks[0], user=user_id, perm="repository.none") Session().commit() # fork shouldn't be there - response = self.app.get( - route_path('repo_forks_data', repo_name=repo_name), - extra_environ=xhr_header) + response = self.app.get(route_path("repo_forks_data", repo_name=repo_name), extra_environ=xhr_header) - assert response.json == {u'data': [], u'draw': None, - u'recordsFiltered': 0, u'recordsTotal': 0} + assert response.json == {"data": [], "draw": None, "recordsFiltered": 0, "recordsTotal": 0} - @pytest.mark.parametrize('url_type', [ - 'repo_fork_new', - 'repo_fork_create' - ]) + @pytest.mark.parametrize("url_type", ["repo_fork_new", "repo_fork_create"]) def test_fork_is_forbidden_on_archived_repo(self, backend, xhr_header, user_util, url_type): - user = user_util.create_user(password='qweqwe') - self.log_user(user.username, 'qweqwe') + user = user_util.create_user(password="qweqwe") + self.log_user(user.username, "qweqwe") # create a temporary repo source = user_util.create_repo(repo_type=backend.alias) @@ -298,19 +266,13 @@ class TestRepoForkViewTests(TestController): repo.archived = True Session().commit() - response = self.app.get( - route_path(url_type, repo_name=repo_name), status=302) + response = self.app.get(route_path(url_type, repo_name=repo_name), status=302) - msg = 'Action not supported for archived repository.' + msg = "Action not supported for archived repository." assert_session_flash(response, msg) class TestSVNFork(TestController): - @pytest.mark.parametrize('route_name', [ - 'repo_fork_create', 'repo_fork_new' - ]) + @pytest.mark.parametrize("route_name", ["repo_fork_create", "repo_fork_new"]) def test_fork_redirects(self, autologin_user, backend_svn, route_name): - - self.app.get(route_path( - route_name, repo_name=backend_svn.repo_name), - status=404) + self.app.get(route_path(route_name, repo_name=backend_svn.repo_name), status=404) diff --git a/rhodecode/apps/repository/tests/test_repo_issue_tracker.py b/rhodecode/apps/repository/tests/test_repo_issue_tracker.py index e82d6950..66003002 100644 --- a/rhodecode/apps/repository/tests/test_repo_issue_tracker.py +++ b/rhodecode/apps/repository/tests/test_repo_issue_tracker.py @@ -25,82 +25,77 @@ from rhodecode.model.settings import SettingsModel, IssueTrackerSettingsModel from rhodecode.tests.routes import route_path - @pytest.mark.usefixtures("app") class TestRepoIssueTracker(object): def test_issuetracker_index(self, autologin_user, backend): repo = backend.create_repo() - response = self.app.get(route_path('edit_repo_issuetracker', - repo_name=repo.repo_name)) + response = self.app.get(route_path("edit_repo_issuetracker", repo_name=repo.repo_name)) assert response.status_code == 200 - def test_add_and_test_issuetracker_patterns( - self, autologin_user, backend, csrf_token, request, xhr_header): - pattern = 'issuetracker_pat' - another_pattern = pattern+'1' - post_url = route_path( - 'edit_repo_issuetracker_update', repo_name=backend.repo.repo_name) + def test_add_and_test_issuetracker_patterns(self, autologin_user, backend, csrf_token, request, xhr_header): + pattern = "issuetracker_pat" + another_pattern = pattern + "1" + post_url = route_path("edit_repo_issuetracker_update", repo_name=backend.repo.repo_name) post_data = { - 'new_pattern_pattern_0': pattern, - 'new_pattern_url_0': 'http://url', - 'new_pattern_prefix_0': 'prefix', - 'new_pattern_description_0': 'description', - 'new_pattern_pattern_1': another_pattern, - 'new_pattern_url_1': '/url1', - 'new_pattern_prefix_1': 'prefix1', - 'new_pattern_description_1': 'description1', - 'csrf_token': csrf_token + "new_pattern_pattern_0": pattern, + "new_pattern_url_0": "http://url", + "new_pattern_prefix_0": "prefix", + "new_pattern_description_0": "description", + "new_pattern_pattern_1": another_pattern, + "new_pattern_url_1": "/url1", + "new_pattern_prefix_1": "prefix1", + "new_pattern_description_1": "description1", + "csrf_token": csrf_token, } self.app.post(post_url, post_data, status=302) self.settings_model = IssueTrackerSettingsModel(repo=backend.repo) settings = self.settings_model.get_repo_settings() self.uid = md5_safe(pattern) - assert settings[self.uid]['pat'] == pattern + assert settings[self.uid]["pat"] == pattern self.another_uid = md5_safe(another_pattern) - assert settings[self.another_uid]['pat'] == another_pattern + assert settings[self.another_uid]["pat"] == another_pattern # test pattern - data = {'test_text': 'example of issuetracker_pat replacement', - 'csrf_token': csrf_token} + data = {"test_text": "example of issuetracker_pat replacement", "csrf_token": csrf_token} response = self.app.post( - route_path('edit_repo_issuetracker_test', - repo_name=backend.repo.repo_name), - extra_environ=xhr_header, params=data) + route_path("edit_repo_issuetracker_test", repo_name=backend.repo.repo_name), + extra_environ=xhr_header, + params=data, + ) - assert response.text == \ - 'example of prefix replacement' + assert ( + response.text + == 'example of prefix replacement' + ) @request.addfinalizer def cleanup(): self.settings_model.delete_entries(self.uid) self.settings_model.delete_entries(self.another_uid) - def test_edit_issuetracker_pattern( - self, autologin_user, backend, csrf_token, request): - entry_key = 'issuetracker_pat_' - pattern = 'issuetracker_pat2' - old_pattern = 'issuetracker_pat' + def test_edit_issuetracker_pattern(self, autologin_user, backend, csrf_token, request): + entry_key = "issuetracker_pat_" + pattern = "issuetracker_pat2" + old_pattern = "issuetracker_pat" old_uid = md5_safe(old_pattern) - sett = SettingsModel(repo=backend.repo).create_or_update_setting( - entry_key+old_uid, old_pattern, 'unicode') + sett = SettingsModel(repo=backend.repo).create_or_update_setting(entry_key + old_uid, old_pattern, "unicode") Session().add(sett) Session().commit() - post_url = route_path( - 'edit_repo_issuetracker_update', repo_name=backend.repo.repo_name) + post_url = route_path("edit_repo_issuetracker_update", repo_name=backend.repo.repo_name) post_data = { - 'new_pattern_pattern_0': pattern, - 'new_pattern_url_0': '/url', - 'new_pattern_prefix_0': 'prefix', - 'new_pattern_description_0': 'description', - 'uid': old_uid, - 'csrf_token': csrf_token + "new_pattern_pattern_0": pattern, + "new_pattern_url_0": "/url", + "new_pattern_prefix_0": "prefix", + "new_pattern_description_0": "description", + "uid": old_uid, + "csrf_token": csrf_token, } self.app.post(post_url, post_data, status=302) self.settings_model = IssueTrackerSettingsModel(repo=backend.repo) settings = self.settings_model.get_repo_settings() self.uid = md5_safe(pattern) - assert settings[self.uid]['pat'] == pattern + assert settings[self.uid]["pat"] == pattern with pytest.raises(KeyError): key = settings[old_uid] @@ -108,26 +103,21 @@ class TestRepoIssueTracker(object): def cleanup(): self.settings_model.delete_entries(self.uid) - def test_delete_issuetracker_pattern( - self, autologin_user, backend, csrf_token, settings_util, xhr_header): + def test_delete_issuetracker_pattern(self, autologin_user, backend, csrf_token, settings_util, xhr_header): repo = backend.create_repo() repo_name = repo.repo_name - entry_key = 'issuetracker_pat_' - pattern = 'issuetracker_pat3' + entry_key = "issuetracker_pat_" + pattern = "issuetracker_pat3" uid = md5_safe(pattern) settings_util.create_repo_rhodecode_setting( - repo=backend.repo, name=entry_key+uid, - value=entry_key, type_='unicode', cleanup=False) + repo=backend.repo, name=entry_key + uid, value=entry_key, type_="unicode", cleanup=False + ) self.app.post( - route_path( - 'edit_repo_issuetracker_delete', - repo_name=backend.repo.repo_name), - { - 'uid': uid, - 'csrf_token': csrf_token, - '': '' - }, extra_environ=xhr_header, status=200) - settings = IssueTrackerSettingsModel( - repo=Repository.get_by_repo_name(repo_name)).get_repo_settings() - assert 'rhodecode_%s%s' % (entry_key, uid) not in settings + route_path("edit_repo_issuetracker_delete", repo_name=backend.repo.repo_name), + {"uid": uid, "csrf_token": csrf_token, "": ""}, + extra_environ=xhr_header, + status=200, + ) + settings = IssueTrackerSettingsModel(repo=Repository.get_by_repo_name(repo_name)).get_repo_settings() + assert "rhodecode_%s%s" % (entry_key, uid) not in settings diff --git a/rhodecode/apps/repository/tests/test_repo_maintainance.py b/rhodecode/apps/repository/tests/test_repo_maintainance.py index 9a348fef..52e14a16 100644 --- a/rhodecode/apps/repository/tests/test_repo_maintainance.py +++ b/rhodecode/apps/repository/tests/test_repo_maintainance.py @@ -27,19 +27,23 @@ fixture = Fixture() def _get_permission_for_user(user, repo): - perm = UserRepoToPerm.query()\ - .filter(UserRepoToPerm.repository == - Repository.get_by_repo_name(repo))\ - .filter(UserRepoToPerm.user == User.get_by_username(user))\ + perm = ( + UserRepoToPerm.query() + .filter(UserRepoToPerm.repository == Repository.get_by_repo_name(repo)) + .filter(UserRepoToPerm.user == User.get_by_username(user)) .all() + ) return perm -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAdminRepoMaintenance(object): - @pytest.mark.parametrize('urlname', [ - 'edit_repo_maintenance', - ]) + @pytest.mark.parametrize( + "urlname", + [ + "edit_repo_maintenance", + ], + ) def test_show_page(self, urlname, app, backend): app.get(route_path(urlname, repo_name=backend.repo_name), status=200) @@ -47,8 +51,11 @@ class TestAdminRepoMaintenance(object): repo_name = backend_hg.repo_name response = app.get( - route_path('edit_repo_maintenance_execute', - repo_name=repo_name,), - extra_environ=xhr_header) + route_path( + "edit_repo_maintenance_execute", + repo_name=repo_name, + ), + extra_environ=xhr_header, + ) - assert "HG Verify repo" in ''.join(response.json) + assert "HG Verify repo" in "".join(response.json) diff --git a/rhodecode/apps/repository/tests/test_repo_permissions.py b/rhodecode/apps/repository/tests/test_repo_permissions.py index 600be8a8..ee969fcc 100644 --- a/rhodecode/apps/repository/tests/test_repo_permissions.py +++ b/rhodecode/apps/repository/tests/test_repo_permissions.py @@ -24,12 +24,9 @@ from rhodecode.tests.routes import route_path @pytest.mark.usefixtures("app") class TestRepoPermissionsView(object): - def test_edit_perms_view(self, user_util, autologin_user): repo = user_util.create_repo() - self.app.get( - route_path('edit_repo_perms', - repo_name=repo.repo_name), status=200) + self.app.get(route_path("edit_repo_perms", repo_name=repo.repo_name), status=200) def test_update_permissions(self, csrf_token, user_util): repo = user_util.create_repo() @@ -40,24 +37,16 @@ class TestRepoPermissionsView(object): # grant new form_data = permission_update_data_generator( - csrf_token, - default='repository.write', - grant=[(user_id, 'repository.write', username, 'user')]) + csrf_token, default="repository.write", grant=[(user_id, "repository.write", username, "user")] + ) - response = self.app.post( - route_path('edit_repo_perms', - repo_name=repo_name), form_data).follow() + response = self.app.post(route_path("edit_repo_perms", repo_name=repo_name), form_data).follow() - assert 'Repository access permissions updated' in response + assert "Repository access permissions updated" in response # revoke given - form_data = permission_update_data_generator( - csrf_token, - default='repository.read', - revoke=[(user_id, 'user')]) + form_data = permission_update_data_generator(csrf_token, default="repository.read", revoke=[(user_id, "user")]) - response = self.app.post( - route_path('edit_repo_perms', - repo_name=repo_name), form_data).follow() + response = self.app.post(route_path("edit_repo_perms", repo_name=repo_name), form_data).follow() - assert 'Repository access permissions updated' in response + assert "Repository access permissions updated" in response diff --git a/rhodecode/apps/repository/tests/test_repo_pullrequests.py b/rhodecode/apps/repository/tests/test_repo_pullrequests.py index 00f9f3d4..7b9eca13 100644 --- a/rhodecode/apps/repository/tests/test_repo_pullrequests.py +++ b/rhodecode/apps/repository/tests/test_repo_pullrequests.py @@ -58,9 +58,7 @@ class TestPullrequestsView(object): repo_name = backend.repo_name response = self.app.get(h.route_path("repo_summary", repo_name=repo_name)) - create_pr_link = 'Create Pull Request' % route_path( - "pullrequest_new", repo_name=repo_name - ) + create_pr_link = 'Create Pull Request' % route_path("pullrequest_new", repo_name=repo_name) response.mustcontain(create_pr_link) def test_create_pr_form_with_raw_commit_id(self, backend): @@ -78,9 +76,7 @@ class TestPullrequestsView(object): @pytest.mark.parametrize("pr_merge_enabled", [True, False]) @pytest.mark.parametrize("range_diff", ["0", "1"]) def test_show(self, pr_util, pr_merge_enabled, range_diff): - pull_request = pr_util.create_pull_request( - mergeable=pr_merge_enabled, enable_notifications=False - ) + pull_request = pr_util.create_pull_request(mergeable=pr_merge_enabled, enable_notifications=False) response = self.app.get( route_path( @@ -125,15 +121,11 @@ class TestPullrequestsView(object): }, { "message": "commit-3", - "changed": [ - FileNode(b"test-file.txt", b"LINE1\nLINE2\nLINE3\nLINE4\n") - ], + "changed": [FileNode(b"test-file.txt", b"LINE1\nLINE2\nLINE3\nLINE4\n")], }, { "message": "commit-4", - "changed": [ - FileNode(b"test-file.txt", b"LINE1\nLINE2\nLINE3\nLINE4\nLINE5\n") - ], + "changed": [FileNode(b"test-file.txt", b"LINE1\nLINE2\nLINE3\nLINE4\nLINE5\n")], }, ] @@ -278,10 +270,7 @@ class TestPullrequestsView(object): return 'cb-addition">{}'.format(text) def cb_context(text): - return ( - '' - "{}".format(text) - ) + return '{}'.format(text) commit_tests = { # in response, not in response @@ -367,9 +356,7 @@ class TestPullrequestsView(object): def test_close_status_visibility(self, pr_util, user_util, csrf_token): # Logout - response = self.app.post( - h.route_path("logout"), params={"csrf_token": csrf_token} - ) + response = self.app.post(h.route_path("logout"), params={"csrf_token": csrf_token}) # Login as regular user response = self.app.post( h.route_path("login"), @@ -461,9 +448,7 @@ class TestPullrequestsView(object): }, ) - assert_session_flash( - response, "Pull request title & description updated.", category="success" - ) + assert_session_flash(response, "Pull request title & description updated.", category="success") pull_request = PullRequest.get(pull_request_id) assert pull_request.title == "New title" @@ -487,9 +472,7 @@ class TestPullrequestsView(object): }, ) - assert_session_flash( - response, "Pull request title & description updated.", category="success" - ) + assert_session_flash(response, "Pull request title & description updated.", category="success") pull_request = PullRequest.get(pull_request_id) assert pull_request.title_safe == "New title {{}} {{2}} {{foo}}" @@ -514,9 +497,7 @@ class TestPullrequestsView(object): }, status=200, ) - assert_session_flash( - response, "Cannot update closed pull requests.", category="error" - ) + assert_session_flash(response, "Cannot update closed pull requests.", category="error") def test_update_invalid_source_reference(self, pr_util, csrf_token): from rhodecode.lib.vcs.backends.base import UpdateFailureReason @@ -537,11 +518,7 @@ class TestPullrequestsView(object): params={"update_commits": "true", "csrf_token": csrf_token}, ) - expected_msg = str( - PullRequestModel.UPDATE_STATUS_MESSAGES[ - UpdateFailureReason.MISSING_SOURCE_REF - ] - ) + expected_msg = str(PullRequestModel.UPDATE_STATUS_MESSAGES[UpdateFailureReason.MISSING_SOURCE_REF]) assert_session_flash(response, expected_msg, category="error") def test_missing_target_reference(self, pr_util, csrf_token): @@ -568,17 +545,11 @@ class TestPullrequestsView(object): True, Reference("commit", "STUB_COMMIT_ID", "STUB_COMMIT_ID"), MergeFailureReason.MISSING_TARGET_REF, - metadata={ - "target_ref": PullRequest.unicode_to_reference(unicode_reference) - }, - ) - response.assert_response().element_contains( - 'div[data-role="merge-message"]', merge_resp.merge_status_message + metadata={"target_ref": PullRequest.unicode_to_reference(unicode_reference)}, ) + response.assert_response().element_contains('div[data-role="merge-message"]', merge_resp.merge_status_message) - def test_comment_and_close_pull_request_custom_message_approved( - self, pr_util, csrf_token, xhr_header - ): + def test_comment_and_close_pull_request_custom_message_approved(self, pr_util, csrf_token, xhr_header): pull_request = pr_util.create_pull_request(approved=True) pull_request_id = pull_request.pull_request_id author = pull_request.user_id @@ -610,9 +581,7 @@ class TestPullrequestsView(object): pull_request = PullRequest.get(pull_request_id) assert pull_request.is_closed() - status = ChangesetStatusModel().get_status( - pull_request.source_repo, pull_request=pull_request - ) + status = ChangesetStatusModel().get_status(pull_request.source_repo, pull_request=pull_request) assert status == ChangesetStatus.STATUS_APPROVED comments = ( ChangesetComment() @@ -623,9 +592,7 @@ class TestPullrequestsView(object): ) assert comments[-1].text == "Closing a PR" - def test_comment_force_close_pull_request_rejected( - self, pr_util, csrf_token, xhr_header - ): + def test_comment_force_close_pull_request_rejected(self, pr_util, csrf_token, xhr_header): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id PullRequestModel().update_reviewers( @@ -660,9 +627,7 @@ class TestPullrequestsView(object): assert journal[-1].action == "repo.pull_request.close" # check only the latest status, not the review status - status = ChangesetStatusModel().get_status( - pull_request.source_repo, pull_request=pull_request - ) + status = ChangesetStatusModel().get_status(pull_request.source_repo, pull_request=pull_request) assert status == ChangesetStatus.STATUS_REJECTED def test_comment_and_close_pull_request(self, pr_util, csrf_token, xhr_header): @@ -685,14 +650,10 @@ class TestPullrequestsView(object): assert pull_request.is_closed() # check only the latest status, not the review status - status = ChangesetStatusModel().get_status( - pull_request.source_repo, pull_request=pull_request - ) + status = ChangesetStatusModel().get_status(pull_request.source_repo, pull_request=pull_request) assert status == ChangesetStatus.STATUS_REJECTED - def test_comment_and_close_pull_request_try_edit_comment( - self, pr_util, csrf_token, xhr_header - ): + def test_comment_and_close_pull_request_try_edit_comment(self, pr_util, csrf_token, xhr_header): pull_request = pr_util.create_pull_request() pull_request_id = pull_request.pull_request_id target_scm = pull_request.target_repo.scm_instance() @@ -719,9 +680,7 @@ class TestPullrequestsView(object): assert pull_request.is_closed() # check only the latest status, not the review status - status = ChangesetStatusModel().get_status( - pull_request.source_repo, pull_request=pull_request - ) + status = ChangesetStatusModel().get_status(pull_request.source_repo, pull_request=pull_request) assert status == ChangesetStatus.STATUS_REJECTED for comment_id in response.json.keys(): @@ -778,12 +737,7 @@ class TestPullrequestsView(object): "version": "0", }, ) - text_form_db = ( - ChangesetComment.query() - .filter(ChangesetComment.comment_id == comment_id) - .first() - .text - ) + text_form_db = ChangesetComment.query().filter(ChangesetComment.comment_id == comment_id).first().text assert test_text == text_form_db def test_comment_and_comment_edit_special(self, pr_util, csrf_token, xhr_header): @@ -876,12 +830,7 @@ class TestPullrequestsView(object): ) assert response.status_int == 409 - text_form_db = ( - ChangesetComment.query() - .filter(ChangesetComment.comment_id == comment_id) - .first() - .text - ) + text_form_db = ChangesetComment.query().filter(ChangesetComment.comment_id == comment_id).first().text assert test_text == text_form_db assert test_text_v2 != text_form_db @@ -895,9 +844,7 @@ class TestPullrequestsView(object): csrf_token, xhr_header, ): - pull_request = pr_util.create_pull_request( - author=user_admin.username, enable_notifications=False - ) + pull_request = pr_util.create_pull_request(author=user_admin.username, enable_notifications=False) comment = CommentsModel().create( text="test", repo=pull_request.target_repo.scm_instance().name, @@ -1039,9 +986,7 @@ class TestPullrequestsView(object): notifications = Notification.query().filter( Notification.created_by == pull_request.author.user_id, Notification.type_ == Notification.TYPE_PULL_REQUEST, - Notification.subject.contains( - "requested a pull request review. !%s" % pull_request_id - ), + Notification.subject.contains("requested a pull request review. !%s" % pull_request_id), ) assert len(notifications.all()) == 1 @@ -1128,7 +1073,6 @@ class TestPullrequestsView(object): response.mustcontain("content_of_change") def test_merge_pull_request_enabled(self, pr_util, csrf_token, rcextensions_modification): - pull_request = pr_util.create_pull_request(approved=True, mergeable=True) pull_request_id = pull_request.pull_request_id repo_name = pull_request.target_repo.scm_instance().name @@ -1139,13 +1083,13 @@ class TestPullrequestsView(object): pull_request_id=pull_request_id, ) - rcstack_location = os.path.dirname(self.app._pyramid_registry.settings['__file__']) - rc_ext_location = os.path.join(rcstack_location, 'rcextension-output.txt') - + rcstack_location = os.path.dirname(self.app._pyramid_registry.settings["__file__"]) + rc_ext_location = os.path.join(rcstack_location, "rcextension-output.txt") mods = [ - ('_push_hook', - f""" + ( + "_push_hook", + f""" import os action = kwargs['action'] commit_ids = kwargs['commit_ids'] @@ -1154,7 +1098,8 @@ class TestPullrequestsView(object): f.write(f'{{action}}'+os.linesep) f.write(f'{{commit_ids}}'+os.linesep) return HookResponse(0, 'HOOK_TEST') - """) + """, + ) ] # Add the hook with rcextensions_modification(rcstack_location, mods, create_if_missing=True, force_create=True): @@ -1184,11 +1129,13 @@ class TestPullrequestsView(object): with open(rc_ext_location) as f: f_data = f.read() - assert 'test-execution' in f_data + assert "test-execution" in f_data for commit_id in pr_commit_ids: - assert f'{commit_id}' in f_data + assert f"{commit_id}" in f_data - def test_merge_pull_request_forbidden_by_pre_push_hook(self, pr_util, csrf_token, rcextensions_modification, caplog): + def test_merge_pull_request_forbidden_by_pre_push_hook( + self, pr_util, csrf_token, rcextensions_modification, caplog + ): caplog.set_level(logging.WARNING, logger="rhodecode.model.pull_request") pull_request = pr_util.create_pull_request(approved=True, mergeable=True) @@ -1201,20 +1148,21 @@ class TestPullrequestsView(object): pull_request_id=pull_request_id, ) - rcstack_location = os.path.dirname(self.app._pyramid_registry.settings['__file__']) + rcstack_location = os.path.dirname(self.app._pyramid_registry.settings["__file__"]) mods = [ - ('_pre_push_hook', - f""" + ( + "_pre_push_hook", + f""" return HookResponse(1, 'HOOK_TEST_FORBIDDEN') - """) + """, + ) ] # Add the hook with rcextensions_modification(rcstack_location, mods, create_if_missing=True, force_create=True): self.app.post(url, params={"csrf_token": csrf_token}) - assert 'Merge failed, not updating the pull request.' in [r[2] for r in caplog.record_tuples] - + assert "Merge failed, not updating the pull request." in [r[2] for r in caplog.record_tuples] def test_merge_pull_request_disabled(self, pr_util, csrf_token): pull_request = pr_util.create_pull_request(mergeable=False) @@ -1231,9 +1179,7 @@ class TestPullrequestsView(object): ).follow() assert response.status_int == 200 - response.mustcontain( - "Merge is not currently possible because of below failed checks." - ) + response.mustcontain("Merge is not currently possible because of below failed checks.") response.mustcontain("Server-side pull request merging is disabled.") @pytest.mark.skip_backends("svn") @@ -1253,14 +1199,10 @@ class TestPullrequestsView(object): assert response.status_int == 200 - response.mustcontain( - "Merge is not currently possible because of below failed checks." - ) + response.mustcontain("Merge is not currently possible because of below failed checks.") response.mustcontain("Pull request reviewer approval is pending.") - def test_merge_pull_request_renders_failure_reason( - self, user_regular, csrf_token, pr_util - ): + def test_merge_pull_request_renders_failure_reason(self, user_regular, csrf_token, pr_util): pull_request = pr_util.create_pull_request(mergeable=True, approved=True) pull_request_id = pull_request.pull_request_id repo_name = pull_request.target_repo.scm_instance().name @@ -1369,7 +1311,6 @@ class TestPullrequestsView(object): {"message": "commit-a"}, # main branch (our PR target) {"message": "commit-b"}, # Initial source {"message": "commit-c"}, - {"message": "commit-a-prime", "branch": "feature", "parents": ["commit-a"]}, # main branch (source) ] @@ -1413,9 +1354,7 @@ class TestPullrequestsView(object): repo_name=target_repo_name, pull_request_id=pull_request_id, ) - self.app.post( - url, params={"update_commits": "true", "csrf_token": csrf_token}, status=200 - ) + self.app.post(url, params={"update_commits": "true", "csrf_token": csrf_token}, status=200) # check that we have now both revisions pull_request = PullRequest.get(pull_request_id) @@ -1435,9 +1374,7 @@ class TestPullrequestsView(object): response.mustcontain("Pull request updated to") response.mustcontain("with 1 added, 1 removed commits.") - def test_update_target_revision_with_removal_of_1_commit_git( - self, backend_git, csrf_token - ): + def test_update_target_revision_with_removal_of_1_commit_git(self, backend_git, csrf_token): backend = backend_git commits = [ {"message": "master-commit-1"}, @@ -1493,13 +1430,9 @@ class TestPullrequestsView(object): repo_name=target_repo_name, pull_request_id=pull_request_id, ) - self.app.post( - url, params={"update_commits": "true", "csrf_token": csrf_token}, status=200 - ) + self.app.post(url, params={"update_commits": "true", "csrf_token": csrf_token}, status=200) - response = self.app.get( - route_path("pullrequest_new", repo_name=target_repo_name) - ) + response = self.app.get(route_path("pullrequest_new", repo_name=target_repo_name)) assert response.status_int == 200 response.mustcontain("Pull request updated to") response.mustcontain("with 0 added, 0 removed commits.") @@ -1510,7 +1443,6 @@ class TestPullrequestsView(object): {"message": "ancestor"}, {"message": "change"}, {"message": "change-2"}, - {"message": "ancestor-new", "parents": ["ancestor"], "branch": "feature"}, {"message": "change-rebased", "branch": "feature"}, ] @@ -1526,8 +1458,12 @@ class TestPullrequestsView(object): commit_ids = pr_util.commit_ids assert pull_request.revisions == [commit_ids["change"]] - assert list(pull_request.target_repo.scm_instance(cache=False).branches.keys()) == [pr_util.backend.default_branch_name] - assert list(pull_request.source_repo.scm_instance(cache=False).branches.keys()) == [pr_util.backend.default_branch_name] + assert list(pull_request.target_repo.scm_instance(cache=False).branches.keys()) == [ + pr_util.backend.default_branch_name + ] + assert list(pull_request.source_repo.scm_instance(cache=False).branches.keys()) == [ + pr_util.backend.default_branch_name + ] branch = "feature" pr_util.update_target_repository(head="ancestor-new", do_fetch=True) @@ -1536,8 +1472,14 @@ class TestPullrequestsView(object): pr_util.update_source_repository(head="change-rebased", do_fetch=True) pr_util.set_pr_source_ref(ref_type="branch", ref_name=branch, ref_commit_id=commit_ids["change-rebased"]) - assert list(pull_request.target_repo.scm_instance(cache=False).branches.keys()) == [pr_util.backend.default_branch_name, branch] - assert list(pull_request.source_repo.scm_instance(cache=False).branches.keys()) == [pr_util.backend.default_branch_name, branch] + assert list(pull_request.target_repo.scm_instance(cache=False).branches.keys()) == [ + pr_util.backend.default_branch_name, + branch, + ] + assert list(pull_request.source_repo.scm_instance(cache=False).branches.keys()) == [ + pr_util.backend.default_branch_name, + branch, + ] Session().add(pr_util.pull_request) Session().commit() @@ -1552,7 +1494,6 @@ class TestPullrequestsView(object): status=200, ) - # response = self.app.get( # route_path( # "pullrequest_show", repo_name=target_repo_name, pull_request_id=pull_request_id, @@ -1566,7 +1507,8 @@ class TestPullrequestsView(object): pull_request = PullRequest.get(pull_request_id) assert pull_request.target_ref == "branch:{branch}:{commit_id}".format( - branch="feature", commit_id=commit_ids["ancestor-new"]) + branch="feature", commit_id=commit_ids["ancestor-new"] + ) assert pull_request.revisions == [commit_ids["change-rebased"]] @@ -1605,17 +1547,11 @@ class TestPullrequestsView(object): # NOTE(marcink): run GC to ensure the commits are gone vcs.run_gc() - response = self.app.get( - route_path( - "pullrequest_show", repo_name=repo_name, pull_request_id=pull_request_id - ) - ) + response = self.app.get(route_path("pullrequest_show", repo_name=repo_name, pull_request_id=pull_request_id)) assert response.status_int == 200 - response.assert_response().element_contains( - "#changeset_compare_view_content .alert strong", "Missing commits" - ) + response.assert_response().element_contains("#changeset_compare_view_content .alert strong", "Missing commits") response.assert_response().element_contains( "#changeset_compare_view_content .alert", "This pull request cannot be displayed, because one or more" @@ -1651,9 +1587,7 @@ class TestPullrequestsView(object): assert response.status_int == 200 - response.assert_response().element_contains( - "#changeset_compare_view_content .alert strong", "Missing commits" - ) + response.assert_response().element_contains("#changeset_compare_view_content .alert strong", "Missing commits") response.assert_response().element_contains( "#changeset_compare_view_content .alert", "This pull request cannot be displayed, because one or more" @@ -1683,29 +1617,17 @@ class TestPullrequestsView(object): else: vcs.strip(pr_util.commit_ids["new-feature"]) - url = route_path( - "pullrequest_update", repo_name=target_repo_name, pull_request_id=pr_id - ) - response = self.app.post( - url, params={"update_commits": "true", "csrf_token": csrf_token} - ) + url = route_path("pullrequest_update", repo_name=target_repo_name, pull_request_id=pr_id) + response = self.app.post(url, params={"update_commits": "true", "csrf_token": csrf_token}) assert response.status_int == 200 - assert json.loads(response.body) == json.loads( - '{"response": true, "redirect_url": null}' - ) + assert json.loads(response.body) == json.loads('{"response": true, "redirect_url": null}') # Make sure that after update, it won't raise 500 errors - response = self.app.get( - route_path( - "pullrequest_show", repo_name=target_repo_name, pull_request_id=pr_id - ) - ) + response = self.app.get(route_path("pullrequest_show", repo_name=target_repo_name, pull_request_id=pr_id)) assert response.status_int == 200 - response.assert_response().element_contains( - "#changeset_compare_view_content .alert strong", "Missing commits" - ) + response.assert_response().element_contains("#changeset_compare_view_content .alert strong", "Missing commits") def test_branch_is_a_link(self, pr_util): pull_request = pr_util.create_pull_request() @@ -1799,28 +1721,18 @@ class TestPullrequestsView(object): repository if the pull request is mergeable. If it is not mergeable the link should not be displayed. """ - pull_request = pr_util.create_pull_request( - mergeable=mergeable, enable_notifications=False - ) + pull_request = pr_util.create_pull_request(mergeable=mergeable, enable_notifications=False) target_repo = pull_request.target_repo.scm_instance() pr_id = pull_request.pull_request_id shadow_url = "{host}/{repo}/pull-request/{pr_id}/repository".format( host=http_host_only_stub, repo=target_repo.name, pr_id=pr_id ) - response = self.app.get( - route_path( - "pullrequest_show", repo_name=target_repo.name, pull_request_id=pr_id - ) - ) + response = self.app.get(route_path("pullrequest_show", repo_name=target_repo.name, pull_request_id=pr_id)) if mergeable: - response.assert_response().element_value_contains( - "input.pr-mergeinfo", shadow_url - ) - response.assert_response().element_value_contains( - "input.pr-mergeinfo ", "pr-merge" - ) + response.assert_response().element_value_contains("input.pr-mergeinfo", shadow_url) + response.assert_response().element_value_contains("input.pr-mergeinfo ", "pr-merge") else: response.assert_response().no_element_exists(".pr-mergeinfo") @@ -1828,12 +1740,8 @@ class TestPullrequestsView(object): @pytest.mark.usefixtures("app") @pytest.mark.backends("git", "hg") class TestPullrequestsControllerDelete(object): - def test_pull_request_delete_button_permissions_admin( - self, autologin_user, user_admin, pr_util - ): - pull_request = pr_util.create_pull_request( - author=user_admin.username, enable_notifications=False - ) + def test_pull_request_delete_button_permissions_admin(self, autologin_user, user_admin, pr_util): + pull_request = pr_util.create_pull_request(author=user_admin.username, enable_notifications=False) response = self.app.get( route_path( @@ -1846,12 +1754,8 @@ class TestPullrequestsControllerDelete(object): response.mustcontain('id="delete_pullrequest"') response.mustcontain("Confirm to delete this pull request") - def test_pull_request_delete_button_permissions_owner( - self, autologin_regular_user, user_regular, pr_util - ): - pull_request = pr_util.create_pull_request( - author=user_regular.username, enable_notifications=False - ) + def test_pull_request_delete_button_permissions_owner(self, autologin_regular_user, user_regular, pr_util): + pull_request = pr_util.create_pull_request(author=user_regular.username, enable_notifications=False) response = self.app.get( route_path( @@ -1867,9 +1771,7 @@ class TestPullrequestsControllerDelete(object): def test_pull_request_delete_button_permissions_forbidden( self, autologin_regular_user, user_regular, user_admin, pr_util ): - pull_request = pr_util.create_pull_request( - author=user_admin.username, enable_notifications=False - ) + pull_request = pr_util.create_pull_request(author=user_admin.username, enable_notifications=False) response = self.app.get( route_path( @@ -1884,13 +1786,9 @@ class TestPullrequestsControllerDelete(object): def test_pull_request_delete_button_permissions_can_update_cannot_delete( self, autologin_regular_user, user_regular, user_admin, pr_util, user_util ): - pull_request = pr_util.create_pull_request( - author=user_admin.username, enable_notifications=False - ) + pull_request = pr_util.create_pull_request(author=user_admin.username, enable_notifications=False) - user_util.grant_user_permission_to_repo( - pull_request.target_repo, user_regular, "repository.write" - ) + user_util.grant_user_permission_to_repo(pull_request.target_repo, user_regular, "repository.write") response = self.app.get( route_path( @@ -1907,9 +1805,7 @@ class TestPullrequestsControllerDelete(object): def test_delete_comment_returns_404_if_comment_does_not_exist( self, autologin_user, pr_util, user_admin, csrf_token, xhr_header ): - pull_request = pr_util.create_pull_request( - author=user_admin.username, enable_notifications=False - ) + pull_request = pr_util.create_pull_request(author=user_admin.username, enable_notifications=False) self.app.post( route_path( @@ -1923,12 +1819,8 @@ class TestPullrequestsControllerDelete(object): status=404, ) - def test_delete_comment( - self, autologin_user, pr_util, user_admin, csrf_token, xhr_header - ): - pull_request = pr_util.create_pull_request( - author=user_admin.username, enable_notifications=False - ) + def test_delete_comment(self, autologin_user, pr_util, user_admin, csrf_token, xhr_header): + pull_request = pr_util.create_pull_request(author=user_admin.username, enable_notifications=False) comment = pr_util.create_comment() comment_id = comment.comment_id @@ -1954,9 +1846,7 @@ class TestPullrequestsControllerDelete(object): "pullrequest_merge", ], ) - def test_pull_request_is_forbidden_on_archived_repo( - self, autologin_user, backend, xhr_header, user_util, url_type - ): + def test_pull_request_is_forbidden_on_archived_repo(self, autologin_user, backend, xhr_header, user_util, url_type): # create a temporary repo source = user_util.create_repo(repo_type=backend.alias) repo_name = source.repo_name @@ -1964,9 +1854,7 @@ class TestPullrequestsControllerDelete(object): repo.archived = True Session().commit() - response = self.app.get( - route_path(url_type, repo_name=repo_name, pull_request_id=1), status=302 - ) + response = self.app.get(route_path(url_type, repo_name=repo_name, pull_request_id=1), status=302) msg = "Action not supported for archived repository." assert_session_flash(response, msg) diff --git a/rhodecode/apps/repository/tests/test_repo_settings.py b/rhodecode/apps/repository/tests/test_repo_settings.py index 0c8621a4..cbbd42fc 100644 --- a/rhodecode/apps/repository/tests/test_repo_settings.py +++ b/rhodecode/apps/repository/tests/test_repo_settings.py @@ -23,8 +23,7 @@ from rhodecode.lib.utils2 import str2bool from rhodecode.lib.vcs.exceptions import RepositoryRequirementError from rhodecode.model.db import Repository, UserRepoToPerm, Permission, User from rhodecode.model.meta import Session -from rhodecode.tests import ( - TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, assert_session_flash) +from rhodecode.tests import TEST_USER_ADMIN_LOGIN, TEST_USER_REGULAR_LOGIN, assert_session_flash from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -32,81 +31,76 @@ fixture = Fixture() def _get_permission_for_user(user, repo): - perm = UserRepoToPerm.query()\ - .filter(UserRepoToPerm.repository == - Repository.get_by_repo_name(repo))\ - .filter(UserRepoToPerm.user == User.get_by_username(user))\ + perm = ( + UserRepoToPerm.query() + .filter(UserRepoToPerm.repository == Repository.get_by_repo_name(repo)) + .filter(UserRepoToPerm.user == User.get_by_username(user)) .all() + ) return perm -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAdminRepoSettings(object): - @pytest.mark.parametrize('urlname', [ - 'edit_repo', - 'edit_repo_caches', - 'edit_repo_perms', - 'edit_repo_advanced', - 'edit_repo_vcs', - 'edit_repo_issuetracker', - 'edit_repo_fields', - 'edit_repo_remote', - 'edit_repo_statistics', - ]) + @pytest.mark.parametrize( + "urlname", + [ + "edit_repo", + "edit_repo_caches", + "edit_repo_perms", + "edit_repo_advanced", + "edit_repo_vcs", + "edit_repo_issuetracker", + "edit_repo_fields", + "edit_repo_remote", + "edit_repo_statistics", + ], + ) def test_show_page(self, urlname, app, backend): app.get(route_path(urlname, repo_name=backend.repo_name), status=200) - def test_edit_accessible_when_missing_requirements( - self, backend_hg, autologin_user): - scm_patcher = mock.patch.object( - Repository, 'scm_instance', side_effect=RepositoryRequirementError) + def test_edit_accessible_when_missing_requirements(self, backend_hg, autologin_user): + scm_patcher = mock.patch.object(Repository, "scm_instance", side_effect=RepositoryRequirementError) with scm_patcher: - self.app.get(route_path('edit_repo', repo_name=backend_hg.repo_name)) + self.app.get(route_path("edit_repo", repo_name=backend_hg.repo_name)) - @pytest.mark.parametrize('update_settings', [ - {'repo_description': 'alter-desc'}, - {'repo_owner': TEST_USER_REGULAR_LOGIN}, - {'repo_private': 'true'}, - {'repo_enable_locking': 'true'}, - {'repo_enable_downloads': 'true'}, - ]) + @pytest.mark.parametrize( + "update_settings", + [ + {"repo_description": "alter-desc"}, + {"repo_owner": TEST_USER_REGULAR_LOGIN}, + {"repo_private": "true"}, + {"repo_enable_locking": "true"}, + {"repo_enable_downloads": "true"}, + ], + ) def test_update_repo_settings(self, update_settings, csrf_token, backend, user_util): repo = user_util.create_repo(repo_type=backend.alias) repo_name = repo.repo_name params = fixture._get_repo_create_params( - csrf_token=csrf_token, - repo_name=repo_name, - repo_type=backend.alias, - repo_owner=TEST_USER_ADMIN_LOGIN, - repo_description='DESC', - - repo_private='false', - repo_enable_locking='false', - repo_enable_downloads='false') + csrf_token=csrf_token, + repo_name=repo_name, + repo_type=backend.alias, + repo_owner=TEST_USER_ADMIN_LOGIN, + repo_description="DESC", + repo_private="false", + repo_enable_locking="false", + repo_enable_downloads="false", + ) params.update(update_settings) - self.app.post( - route_path('edit_repo', repo_name=repo_name), - params=params, status=302) + self.app.post(route_path("edit_repo", repo_name=repo_name), params=params, status=302) repo = Repository.get_by_repo_name(repo_name) - assert repo.user.username == \ - update_settings.get('repo_owner', repo.user.username) + assert repo.user.username == update_settings.get("repo_owner", repo.user.username) - assert repo.description == \ - update_settings.get('repo_description', repo.description) + assert repo.description == update_settings.get("repo_description", repo.description) - assert repo.private == \ - str2bool(update_settings.get( - 'repo_private', repo.private)) + assert repo.private == str2bool(update_settings.get("repo_private", repo.private)) - assert repo.enable_locking == \ - str2bool(update_settings.get( - 'repo_enable_locking', repo.enable_locking)) + assert repo.enable_locking == str2bool(update_settings.get("repo_enable_locking", repo.enable_locking)) - assert repo.enable_downloads == \ - str2bool(update_settings.get( - 'repo_enable_downloads', repo.enable_downloads)) + assert repo.enable_downloads == str2bool(update_settings.get("repo_enable_downloads", repo.enable_downloads)) def test_update_repo_name_via_settings(self, csrf_token, user_util, backend): repo = user_util.create_repo(repo_type=backend.alias) @@ -114,20 +108,19 @@ class TestAdminRepoSettings(object): repo_group = user_util.create_repo_group() repo_group_name = repo_group.group_name - new_name = repo_group_name + '_' + repo_name + new_name = repo_group_name + "_" + repo_name params = fixture._get_repo_create_params( - csrf_token=csrf_token, - repo_name=new_name, - repo_type=backend.alias, - repo_owner=TEST_USER_ADMIN_LOGIN, - repo_description='DESC', - repo_private='false', - repo_enable_locking='false', - repo_enable_downloads='false') - self.app.post( - route_path('edit_repo', repo_name=repo_name), - params=params, status=302) + csrf_token=csrf_token, + repo_name=new_name, + repo_type=backend.alias, + repo_owner=TEST_USER_ADMIN_LOGIN, + repo_description="DESC", + repo_private="false", + repo_enable_locking="false", + repo_enable_downloads="false", + ) + self.app.post(route_path("edit_repo", repo_name=repo_name), params=params, status=302) repo = Repository.get_by_repo_name(new_name) assert repo.repo_name == new_name @@ -139,73 +132,72 @@ class TestAdminRepoSettings(object): repo_group_name = repo_group.group_name repo_group_id = repo_group.group_id - new_name = repo_group_name + '/' + repo_name + new_name = repo_group_name + "/" + repo_name params = fixture._get_repo_create_params( - csrf_token=csrf_token, - repo_name=repo_name, - repo_type=backend.alias, - repo_owner=TEST_USER_ADMIN_LOGIN, - repo_description='DESC', - repo_group=repo_group_id, - repo_private='false', - repo_enable_locking='false', - repo_enable_downloads='false') - self.app.post( - route_path('edit_repo', repo_name=repo_name), - params=params, status=302) + csrf_token=csrf_token, + repo_name=repo_name, + repo_type=backend.alias, + repo_owner=TEST_USER_ADMIN_LOGIN, + repo_description="DESC", + repo_group=repo_group_id, + repo_private="false", + repo_enable_locking="false", + repo_enable_downloads="false", + ) + self.app.post(route_path("edit_repo", repo_name=repo_name), params=params, status=302) repo = Repository.get_by_repo_name(new_name) assert repo.repo_name == new_name - def test_set_private_flag_sets_default_user_permissions_to_none( - self, autologin_user, backend, csrf_token): - + def test_set_private_flag_sets_default_user_permissions_to_none(self, autologin_user, backend, csrf_token): # initially repository perm should be read - perm = _get_permission_for_user(user='default', repo=backend.repo_name) + perm = _get_permission_for_user(user="default", repo=backend.repo_name) assert len(perm) == 1 - assert perm[0].permission.permission_name == 'repository.read' + assert perm[0].permission.permission_name == "repository.read" assert not backend.repo.private response = self.app.post( - route_path('edit_repo', repo_name=backend.repo_name), + route_path("edit_repo", repo_name=backend.repo_name), params=fixture._get_repo_create_params( - repo_private='true', + repo_private="true", repo_name=backend.repo_name, repo_type=backend.alias, repo_owner=TEST_USER_ADMIN_LOGIN, - csrf_token=csrf_token), status=302) + csrf_token=csrf_token, + ), + status=302, + ) - assert_session_flash( - response, - msg='Repository `%s` updated successfully' % (backend.repo_name)) + assert_session_flash(response, msg="Repository `%s` updated successfully" % (backend.repo_name)) repo = Repository.get_by_repo_name(backend.repo_name) assert repo.private is True # now the repo default permission should be None - perm = _get_permission_for_user(user='default', repo=backend.repo_name) + perm = _get_permission_for_user(user="default", repo=backend.repo_name) assert len(perm) == 1 - assert perm[0].permission.permission_name == 'repository.none' + assert perm[0].permission.permission_name == "repository.none" response = self.app.post( - route_path('edit_repo', repo_name=backend.repo_name), + route_path("edit_repo", repo_name=backend.repo_name), params=fixture._get_repo_create_params( - repo_private='false', + repo_private="false", repo_name=backend.repo_name, repo_type=backend.alias, repo_owner=TEST_USER_ADMIN_LOGIN, - csrf_token=csrf_token), status=302) + csrf_token=csrf_token, + ), + status=302, + ) - assert_session_flash( - response, - msg='Repository `%s` updated successfully' % (backend.repo_name)) + assert_session_flash(response, msg="Repository `%s` updated successfully" % (backend.repo_name)) assert backend.repo.private is False # we turn off private now the repo default permission should stay None - perm = _get_permission_for_user(user='default', repo=backend.repo_name) + perm = _get_permission_for_user(user="default", repo=backend.repo_name) assert len(perm) == 1 - assert perm[0].permission.permission_name == 'repository.none' + assert perm[0].permission.permission_name == "repository.none" # update this permission back - perm[0].permission = Permission.get_by_key('repository.read') + perm[0].permission = Permission.get_by_key("repository.read") Session().add(perm[0]) Session().commit() diff --git a/rhodecode/apps/repository/tests/test_repo_settings_advanced.py b/rhodecode/apps/repository/tests/test_repo_settings_advanced.py index 24a910ad..7a484d61 100644 --- a/rhodecode/apps/repository/tests/test_repo_settings_advanced.py +++ b/rhodecode/apps/repository/tests/test_repo_settings_advanced.py @@ -21,8 +21,7 @@ import pytest from rhodecode.lib.str_utils import safe_str from rhodecode.model.db import Repository from rhodecode.model.repo import RepoModel -from rhodecode.tests import ( - HG_REPO, GIT_REPO, assert_session_flash, no_newline_id_generator) +from rhodecode.tests import HG_REPO, GIT_REPO, assert_session_flash, no_newline_id_generator from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.utils import repo_on_filesystem from rhodecode.tests.routes import route_path @@ -30,123 +29,101 @@ from rhodecode.tests.routes import route_path fixture = Fixture() -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAdminRepoSettingsAdvanced(object): - def test_set_repo_fork_has_no_self_id(self, autologin_user, backend): repo = backend.repo - response = self.app.get( - route_path('edit_repo_advanced', repo_name=backend.repo_name)) + response = self.app.get(route_path("edit_repo_advanced", repo_name=backend.repo_name)) opt = """""" % repo.repo_id response.mustcontain(no=[opt]) - def test_set_fork_of_target_repo( - self, autologin_user, backend, csrf_token): - target_repo = 'target_%s' % backend.alias + def test_set_fork_of_target_repo(self, autologin_user, backend, csrf_token): + target_repo = "target_%s" % backend.alias fixture.create_repo(target_repo, repo_type=backend.alias) repo2 = Repository.get_by_repo_name(target_repo) response = self.app.post( - route_path('edit_repo_advanced_fork', repo_name=backend.repo_name), - params={'id_fork_of': repo2.repo_id, - 'csrf_token': csrf_token}) + route_path("edit_repo_advanced_fork", repo_name=backend.repo_name), + params={"id_fork_of": repo2.repo_id, "csrf_token": csrf_token}, + ) repo = Repository.get_by_repo_name(backend.repo_name) repo2 = Repository.get_by_repo_name(target_repo) - assert_session_flash( - response, - 'Marked repo %s as fork of %s' % (repo.repo_name, repo2.repo_name)) + assert_session_flash(response, "Marked repo %s as fork of %s" % (repo.repo_name, repo2.repo_name)) assert repo.fork == repo2 response = response.follow() # check if given repo is selected opt = 'This repository is a fork of %s' % ( - route_path('repo_summary', repo_name=repo2.repo_name), - repo2.repo_name) + route_path("repo_summary", repo_name=repo2.repo_name), + repo2.repo_name, + ) response.mustcontain(opt) - fixture.destroy_repo(target_repo, forks='detach') + fixture.destroy_repo(target_repo, forks="detach") @pytest.mark.backends("hg", "git") - def test_set_fork_of_other_type_repo( - self, autologin_user, backend, csrf_token): + def test_set_fork_of_other_type_repo(self, autologin_user, backend, csrf_token): TARGET_REPO_MAP = { - 'git': { - 'type': 'hg', - 'repo_name': HG_REPO}, - 'hg': { - 'type': 'git', - 'repo_name': GIT_REPO}, + "git": {"type": "hg", "repo_name": HG_REPO}, + "hg": {"type": "git", "repo_name": GIT_REPO}, } target_repo = TARGET_REPO_MAP[backend.alias] - repo2 = Repository.get_by_repo_name(target_repo['repo_name']) + repo2 = Repository.get_by_repo_name(target_repo["repo_name"]) response = self.app.post( - route_path('edit_repo_advanced_fork', repo_name=backend.repo_name), - params={'id_fork_of': repo2.repo_id, - 'csrf_token': csrf_token}) - assert_session_flash( - response, - 'Cannot set repository as fork of repository with other type') + route_path("edit_repo_advanced_fork", repo_name=backend.repo_name), + params={"id_fork_of": repo2.repo_id, "csrf_token": csrf_token}, + ) + assert_session_flash(response, "Cannot set repository as fork of repository with other type") def test_set_fork_of_none(self, autologin_user, backend, csrf_token): # mark it as None response = self.app.post( - route_path('edit_repo_advanced_fork', repo_name=backend.repo_name), - params={'id_fork_of': None, - 'csrf_token': csrf_token}) - assert_session_flash( - response, - 'Marked repo %s as fork of %s' - % (backend.repo_name, "Nothing")) + route_path("edit_repo_advanced_fork", repo_name=backend.repo_name), + params={"id_fork_of": None, "csrf_token": csrf_token}, + ) + assert_session_flash(response, "Marked repo %s as fork of %s" % (backend.repo_name, "Nothing")) assert backend.repo.fork is None def test_set_fork_of_same_repo(self, autologin_user, backend, csrf_token): repo = Repository.get_by_repo_name(backend.repo_name) response = self.app.post( - route_path('edit_repo_advanced_fork', repo_name=backend.repo_name), - params={'id_fork_of': repo.repo_id, 'csrf_token': csrf_token}) - assert_session_flash( - response, 'An error occurred during this operation') + route_path("edit_repo_advanced_fork", repo_name=backend.repo_name), + params={"id_fork_of": repo.repo_id, "csrf_token": csrf_token}, + ) + assert_session_flash(response, "An error occurred during this operation") - @pytest.mark.parametrize( - "suffix", - ['', u'ąęł' , '123'], - ids=no_newline_id_generator) + @pytest.mark.parametrize("suffix", ["", "ąęł", "123"], ids=no_newline_id_generator) def test_advanced_repo_delete(self, autologin_user, backend, suffix, csrf_token): repo = backend.create_repo(name_suffix=suffix) repo_name = repo.repo_name repo_name_str = safe_str(repo.repo_name) response = self.app.post( - route_path('edit_repo_advanced_delete', repo_name=repo_name_str), - params={'csrf_token': csrf_token}) - assert_session_flash(response, - u'Deleted repository `{}`'.format(repo_name)) + route_path("edit_repo_advanced_delete", repo_name=repo_name_str), params={"csrf_token": csrf_token} + ) + assert_session_flash(response, "Deleted repository `{}`".format(repo_name)) response.follow() # check if repo was deleted from db assert RepoModel().get_by_repo_name(repo_name) is None assert not repo_on_filesystem(repo_name_str) - @pytest.mark.parametrize( - "suffix", - ['', u'ąęł' , '123'], - ids=no_newline_id_generator) + @pytest.mark.parametrize("suffix", ["", "ąęł", "123"], ids=no_newline_id_generator) def test_advanced_repo_archive(self, autologin_user, backend, suffix, csrf_token): repo = backend.create_repo(name_suffix=suffix) repo_name = repo.repo_name repo_name_str = safe_str(repo.repo_name) response = self.app.post( - route_path('edit_repo_advanced_archive', repo_name=repo_name_str), - params={'csrf_token': csrf_token}) + route_path("edit_repo_advanced_archive", repo_name=repo_name_str), params={"csrf_token": csrf_token} + ) - assert_session_flash(response, - u'Archived repository `{}`'.format(repo_name)) + assert_session_flash(response, "Archived repository `{}`".format(repo_name)) - response = self.app.get(route_path('repo_summary', repo_name=repo_name_str)) - response.mustcontain('This repository has been archived. It is now read-only.') + response = self.app.get(route_path("repo_summary", repo_name=repo_name_str)) + response.mustcontain("This repository has been archived. It is now read-only.") # check if repo was deleted from db assert RepoModel().get_by_repo_name(repo_name).archived is True diff --git a/rhodecode/apps/repository/tests/test_repo_summary.py b/rhodecode/apps/repository/tests/test_repo_summary.py index 92c9975e..7dc30bb1 100644 --- a/rhodecode/apps/repository/tests/test_repo_summary.py +++ b/rhodecode/apps/repository/tests/test_repo_summary.py @@ -40,98 +40,76 @@ fixture = Fixture() def assert_clone_url(response, server, repo, disabled=False): - response.mustcontain( ''.format( - server=server, repo=repo, disabled='disabled ' if disabled else ' ') + server=server, repo=repo, disabled="disabled " if disabled else " " + ) ) -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestSummaryView(object): - def test_index(self, autologin_user, backend, http_host_only_stub): repo_id = backend.repo.repo_id repo_name = backend.repo_name - response = self.app.get( - route_path('repo_summary', repo_name=repo_name)) + response = self.app.get(route_path("repo_summary", repo_name=repo_name)) # repo type - response.mustcontain( - '' % (backend.alias, ) - ) + response.mustcontain('' % (backend.alias,)) # public/private - response.mustcontain( - """""" - ) + response.mustcontain("""""") # clone url... assert_clone_url(response, http_host_only_stub, repo_name) - assert_clone_url(response, http_host_only_stub, f'_{repo_id}') - - def test_index_svn_without_proxy( - self, autologin_user, backend_svn, http_host_only_stub): + assert_clone_url(response, http_host_only_stub, f"_{repo_id}") + def test_index_svn_without_proxy(self, autologin_user, backend_svn, http_host_only_stub): repo_id = backend_svn.repo.repo_id repo_name = backend_svn.repo_name # by default the SVN is enabled now, this is how inputs look when it's disabled - with mock.patch('rhodecode.lib.helpers.is_svn_without_proxy', return_value=True): - - response = self.app.get( - route_path('repo_summary', repo_name=repo_name), - status=200) + with mock.patch("rhodecode.lib.helpers.is_svn_without_proxy", return_value=True): + response = self.app.get(route_path("repo_summary", repo_name=repo_name), status=200) # clone url test... assert_clone_url(response, http_host_only_stub, repo_name, disabled=True) - assert_clone_url(response, http_host_only_stub, f'_{repo_id}', disabled=True) - - def test_index_with_trailing_slash( - self, autologin_user, backend, http_host_only_stub): + assert_clone_url(response, http_host_only_stub, f"_{repo_id}", disabled=True) + def test_index_with_trailing_slash(self, autologin_user, backend, http_host_only_stub): repo_id = backend.repo.repo_id repo_name = backend.repo_name - trailing_slash = '/' - response = self.app.get( - route_path('repo_summary', repo_name=repo_name) + trailing_slash, - status=200) + trailing_slash = "/" + response = self.app.get(route_path("repo_summary", repo_name=repo_name) + trailing_slash, status=200) # clone url... assert_clone_url(response, http_host_only_stub, repo_name) - assert_clone_url(response, http_host_only_stub, f'_{repo_id}') + assert_clone_url(response, http_host_only_stub, f"_{repo_id}") def test_index_by_id(self, autologin_user, backend): repo_id = backend.repo.repo_id - response = self.app.get( - route_path('repo_summary', repo_name=f'_{repo_id}')) + response = self.app.get(route_path("repo_summary", repo_name=f"_{repo_id}")) # repo type - response.mustcontain( - '' % (backend.alias, ) - ) + response.mustcontain('' % (backend.alias,)) # public/private - response.mustcontain( - """""" - ) + response.mustcontain("""""") def test_index_by_repo_having_id_path_in_name_hg(self, autologin_user): - fixture.create_repo(name='repo_1') - response = self.app.get(route_path('repo_summary', repo_name='repo_1')) + fixture.create_repo(name="repo_1") + response = self.app.get(route_path("repo_summary", repo_name="repo_1")) try: response.mustcontain("repo_1") finally: - RepoModel().delete(Repository.get_by_repo_name('repo_1')) + RepoModel().delete(Repository.get_by_repo_name("repo_1")) Session().commit() - def test_index_with_anonymous_access_disabled( - self, backend, disable_anonymous_user): - response = self.app.get( - route_path('repo_summary', repo_name=backend.repo_name), status=302) - assert 'login' in response.location + def test_index_with_anonymous_access_disabled(self, backend, disable_anonymous_user): + response = self.app.get(route_path("repo_summary", repo_name=backend.repo_name), status=302) + assert "login" in response.location def _enable_stats(self, repo): r = Repository.get_by_repo_name(repo) @@ -140,7 +118,7 @@ class TestSummaryView(object): Session().commit() expected_trending = { - 'hg': { + "hg": { "py": {"count": 68, "desc": ["Python"]}, "rst": {"count": 16, "desc": ["Rst"]}, "css": {"count": 2, "desc": ["Css"]}, @@ -150,9 +128,9 @@ class TestSummaryView(object): "html": {"count": 1, "desc": ["EvoqueHtml", "Html"]}, "ini": {"count": 1, "desc": ["Ini"]}, "js": {"count": 1, "desc": ["Javascript"]}, - "makefile": {"count": 1, "desc": ["Makefile", "Makefile"]} + "makefile": {"count": 1, "desc": ["Makefile", "Makefile"]}, }, - 'git': { + "git": { "py": {"count": 68, "desc": ["Python"]}, "rst": {"count": 16, "desc": ["Rst"]}, "css": {"count": 2, "desc": ["Css"]}, @@ -162,9 +140,9 @@ class TestSummaryView(object): "html": {"count": 1, "desc": ["EvoqueHtml", "Html"]}, "ini": {"count": 1, "desc": ["Ini"]}, "js": {"count": 1, "desc": ["Javascript"]}, - "makefile": {"count": 1, "desc": ["Makefile", "Makefile"]} + "makefile": {"count": 1, "desc": ["Makefile", "Makefile"]}, }, - 'svn': { + "svn": { "py": {"count": 75, "desc": ["Python"]}, "rst": {"count": 16, "desc": ["Rst"]}, "html": {"count": 11, "desc": ["EvoqueHtml", "Html"]}, @@ -174,17 +152,15 @@ class TestSummaryView(object): "ini": {"count": 1, "desc": ["Ini"]}, "js": {"count": 1, "desc": ["Javascript"]}, "makefile": {"count": 1, "desc": ["Makefile", "Makefile"]}, - "sh": {"count": 1, "desc": ["Bash"]} + "sh": {"count": 1, "desc": ["Bash"]}, }, } def test_repo_stats(self, autologin_user, backend, xhr_header): response = self.app.get( - route_path( - 'repo_stats', repo_name=backend.repo_name, commit_id='tip'), - extra_environ=xhr_header, - status=200) - assert re.match(r'6[\d\.]+ KiB', response.json['size']) + route_path("repo_stats", repo_name=backend.repo_name, commit_id="tip"), extra_environ=xhr_header, status=200 + ) + assert re.match(r"6[\d\.]+ KiB", response.json["size"]) def test_repo_stats_code_stats_enabled(self, autologin_user, backend, xhr_header): repo_name = backend.repo_name @@ -194,62 +170,50 @@ class TestSummaryView(object): ScmModel().mark_for_invalidation(repo_name) response = self.app.get( - route_path( - 'repo_stats', repo_name=backend.repo_name, commit_id='tip'), - extra_environ=xhr_header, - status=200) + route_path("repo_stats", repo_name=backend.repo_name, commit_id="tip"), extra_environ=xhr_header, status=200 + ) expected_data = self.expected_trending[backend.alias] - returned_stats = response.json['code_stats'] + returned_stats = response.json["code_stats"] for k, v in expected_data.items(): assert v == returned_stats[k] def test_repo_refs_data(self, backend): - response = self.app.get( - route_path('repo_refs_data', repo_name=backend.repo_name), - status=200) + response = self.app.get(route_path("repo_refs_data", repo_name=backend.repo_name), status=200) # Ensure that there is the correct amount of items in the result repo = backend.repo.scm_instance() - data = response.json['results'] - items = sum(len(section['children']) for section in data) + data = response.json["results"] + items = sum(len(section["children"]) for section in data) repo_refs = len(repo.branches) + len(repo.tags) + len(repo.bookmarks) assert items == repo_refs - def test_index_shows_missing_requirements_message( - self, backend, autologin_user): + def test_index_shows_missing_requirements_message(self, backend, autologin_user): repo_name = backend.repo_name - scm_patcher = mock.patch.object( - Repository, 'scm_instance', side_effect=RepositoryRequirementError) + scm_patcher = mock.patch.object(Repository, "scm_instance", side_effect=RepositoryRequirementError) with scm_patcher: - response = self.app.get( - route_path('repo_summary', repo_name=repo_name)) + response = self.app.get(route_path("repo_summary", repo_name=repo_name)) assert_response = response.assert_response() + assert_response.element_contains(".main .alert-warning strong", "Missing requirements") assert_response.element_contains( - '.main .alert-warning strong', 'Missing requirements') - assert_response.element_contains( - '.main .alert-warning', - 'Commits cannot be displayed, because this repository ' - 'uses one or more extensions, which was not enabled.') + ".main .alert-warning", + "Commits cannot be displayed, because this repository uses one or more extensions, which was not enabled.", + ) - def test_missing_requirements_page_does_not_contains_switch_to( - self, autologin_user, backend): + def test_missing_requirements_page_does_not_contains_switch_to(self, autologin_user, backend): repo_name = backend.repo_name - scm_patcher = mock.patch.object( - Repository, 'scm_instance', side_effect=RepositoryRequirementError) + scm_patcher = mock.patch.object(Repository, "scm_instance", side_effect=RepositoryRequirementError) with scm_patcher: - response = self.app.get(route_path('repo_summary', repo_name=repo_name)) - response.mustcontain(no='Switch To') + response = self.app.get(route_path("repo_summary", repo_name=repo_name)) + response.mustcontain(no="Switch To") -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestRepoLocation(object): - - @pytest.mark.parametrize("suffix", [u'', u'ąęł'], ids=['', 'non-ascii']) - def test_missing_filesystem_repo( - self, autologin_user, backend, suffix, csrf_token): + @pytest.mark.parametrize("suffix", ["", "ąęł"], ids=["", "non-ascii"]) + def test_missing_filesystem_repo(self, autologin_user, backend, suffix, csrf_token): repo = backend.create_repo(name_suffix=suffix) repo_name = repo.repo_name @@ -263,16 +227,15 @@ class TestRepoLocation(object): # check if repo is not in the filesystem assert not repo_on_filesystem(repo_name) - response = self.app.get( - route_path('repo_summary', repo_name=safe_str(repo_name)), status=302) + response = self.app.get(route_path("repo_summary", repo_name=safe_str(repo_name)), status=302) - msg = f'The repository `{repo_name}` cannot be loaded in filesystem. ' \ - f'Please check if it exist, or is not damaged.' + msg = ( + f"The repository `{repo_name}` cannot be loaded in filesystem. Please check if it exist, or is not damaged." + ) assert_session_flash(response, msg) - @pytest.mark.parametrize("suffix", [u'', u'ąęł'], ids=['', 'non-ascii']) - def test_missing_filesystem_repo_on_repo_check( - self, autologin_user, backend, suffix, csrf_token): + @pytest.mark.parametrize("suffix", ["", "ąęł"], ids=["", "non-ascii"]) + def test_missing_filesystem_repo_on_repo_check(self, autologin_user, backend, suffix, csrf_token): repo = backend.create_repo(name_suffix=suffix) repo_name = repo.repo_name @@ -287,16 +250,14 @@ class TestRepoLocation(object): assert not repo_on_filesystem(repo_name) # flush the session - self.app.get( - route_path('repo_summary', repo_name=safe_str(repo_name)), - status=302) + self.app.get(route_path("repo_summary", repo_name=safe_str(repo_name)), status=302) - response = self.app.get( - route_path('repo_creating_check', repo_name=safe_str(repo_name)), - status=200) - msg = 'The repository `%s` cannot be loaded in filesystem. ' \ - 'Please check if it exist, or is not damaged.' % repo_name - assert_session_flash(response, msg ) + response = self.app.get(route_path("repo_creating_check", repo_name=safe_str(repo_name)), status=200) + msg = ( + "The repository `%s` cannot be loaded in filesystem. " + "Please check if it exist, or is not damaged." % repo_name + ) + assert_session_flash(response, msg) @pytest.fixture() @@ -304,7 +265,7 @@ def summary_view(context_stub, request_stub, user_util): """ Bootstrap view to test the view functions """ - request_stub.matched_route = AttributeDict(name='test_view') + request_stub.matched_route = AttributeDict(name="test_view") request_stub.user = user_util.create_user().AuthUser() request_stub.db_repo = user_util.create_repo() @@ -313,201 +274,207 @@ def summary_view(context_stub, request_stub, user_util): return view -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestCreateReferenceData(object): - @pytest.fixture() def example_refs(self): - section_1_refs = OrderedDict((('a', 'a_id'), ('b', 'b_id'))) + section_1_refs = OrderedDict((("a", "a_id"), ("b", "b_id"))) example_refs = [ - ('section_1', section_1_refs, 't1'), - ('section_2', {'c': 'c_id'}, 't2'), + ("section_1", section_1_refs, "t1"), + ("section_2", {"c": "c_id"}, "t2"), ] return example_refs def test_generates_refs_based_on_commit_ids(self, example_refs, summary_view): repo = mock.Mock() - repo.name = 'test-repo' - repo.alias = 'git' - full_repo_name = 'pytest-repo-group/' + repo.name + repo.name = "test-repo" + repo.alias = "git" + full_repo_name = "pytest-repo-group/" + repo.name - result = summary_view._create_reference_data( - repo, full_repo_name, example_refs) + result = summary_view._create_reference_data(repo, full_repo_name, example_refs) - expected_files_url = '/{}/files/'.format(full_repo_name) + expected_files_url = "/{}/files/".format(full_repo_name) expected_result = [ { - 'children': [ + "children": [ { - 'id': 'a', 'idx': 0, 'raw_id': 'a_id', 'text': 'a', 'type': 't1', - 'files_url': expected_files_url + 'a/?at=a', + "id": "a", + "idx": 0, + "raw_id": "a_id", + "text": "a", + "type": "t1", + "files_url": expected_files_url + "a/?at=a", }, { - 'id': 'b', 'idx': 0, 'raw_id': 'b_id', 'text': 'b', 'type': 't1', - 'files_url': expected_files_url + 'b/?at=b', - } + "id": "b", + "idx": 0, + "raw_id": "b_id", + "text": "b", + "type": "t1", + "files_url": expected_files_url + "b/?at=b", + }, ], - 'text': 'section_1' + "text": "section_1", }, { - 'children': [ + "children": [ { - 'id': 'c', 'idx': 0, 'raw_id': 'c_id', 'text': 'c', 'type': 't2', - 'files_url': expected_files_url + 'c/?at=c', + "id": "c", + "idx": 0, + "raw_id": "c_id", + "text": "c", + "type": "t2", + "files_url": expected_files_url + "c/?at=c", } ], - 'text': 'section_2' - }] + "text": "section_2", + }, + ] assert result == expected_result def test_generates_refs_with_path_for_svn(self, example_refs, summary_view): repo = mock.Mock() - repo.name = 'test-repo' - repo.alias = 'svn' - full_repo_name = 'pytest-repo-group/' + repo.name + repo.name = "test-repo" + repo.alias = "svn" + full_repo_name = "pytest-repo-group/" + repo.name - result = summary_view._create_reference_data( - repo, full_repo_name, example_refs) + result = summary_view._create_reference_data(repo, full_repo_name, example_refs) - expected_files_url = '/{}/files/'.format(full_repo_name) + expected_files_url = "/{}/files/".format(full_repo_name) expected_result = [ { - 'children': [ + "children": [ { - 'id': 'a@a_id', 'idx': 0, 'raw_id': 'a_id', - 'text': 'a', 'type': 't1', - 'files_url': expected_files_url + 'a_id/a?at=a', + "id": "a@a_id", + "idx": 0, + "raw_id": "a_id", + "text": "a", + "type": "t1", + "files_url": expected_files_url + "a_id/a?at=a", }, { - 'id': 'b@b_id', 'idx': 0, 'raw_id': 'b_id', - 'text': 'b', 'type': 't1', - 'files_url': expected_files_url + 'b_id/b?at=b', - } + "id": "b@b_id", + "idx": 0, + "raw_id": "b_id", + "text": "b", + "type": "t1", + "files_url": expected_files_url + "b_id/b?at=b", + }, ], - 'text': 'section_1' + "text": "section_1", }, { - 'children': [ + "children": [ { - 'id': 'c@c_id', 'idx': 0, 'raw_id': 'c_id', - 'text': 'c', 'type': 't2', - 'files_url': expected_files_url + 'c_id/c?at=c', + "id": "c@c_id", + "idx": 0, + "raw_id": "c_id", + "text": "c", + "type": "t2", + "files_url": expected_files_url + "c_id/c?at=c", } ], - 'text': 'section_2' - } + "text": "section_2", + }, ] assert result == expected_result class TestCreateFilesUrl(object): - def test_creates_non_svn_url(self, app, summary_view): repo = mock.Mock() - repo.name = 'abcde' - full_repo_name = 'test-repo-group/' + repo.name - ref_name = 'branch1' - raw_id = 'deadbeef0123456789' + repo.name = "abcde" + full_repo_name = "test-repo-group/" + repo.name + ref_name = "branch1" + raw_id = "deadbeef0123456789" is_svn = False - with mock.patch('rhodecode.lib.helpers.route_path') as url_mock: - result = summary_view._create_files_url( - repo, full_repo_name, ref_name, raw_id, is_svn) + with mock.patch("rhodecode.lib.helpers.route_path") as url_mock: + result = summary_view._create_files_url(repo, full_repo_name, ref_name, raw_id, is_svn) url_mock.assert_called_once_with( - 'repo_files', repo_name=full_repo_name, commit_id=ref_name, - f_path='', _query=dict(at=ref_name)) + "repo_files", repo_name=full_repo_name, commit_id=ref_name, f_path="", _query=dict(at=ref_name) + ) assert result == url_mock.return_value def test_creates_svn_url(self, app, summary_view): repo = mock.Mock() - repo.name = 'abcde' - full_repo_name = 'test-repo-group/' + repo.name - ref_name = 'branch1' - raw_id = 'deadbeef0123456789' + repo.name = "abcde" + full_repo_name = "test-repo-group/" + repo.name + ref_name = "branch1" + raw_id = "deadbeef0123456789" is_svn = True - with mock.patch('rhodecode.lib.helpers.route_path') as url_mock: - result = summary_view._create_files_url( - repo, full_repo_name, ref_name, raw_id, is_svn) + with mock.patch("rhodecode.lib.helpers.route_path") as url_mock: + result = summary_view._create_files_url(repo, full_repo_name, ref_name, raw_id, is_svn) url_mock.assert_called_once_with( - 'repo_files', repo_name=full_repo_name, f_path=ref_name, - commit_id=raw_id, _query=dict(at=ref_name)) + "repo_files", repo_name=full_repo_name, f_path=ref_name, commit_id=raw_id, _query=dict(at=ref_name) + ) assert result == url_mock.return_value def test_name_has_slashes(self, app, summary_view): repo = mock.Mock() - repo.name = 'abcde' - full_repo_name = 'test-repo-group/' + repo.name - ref_name = 'branch1/branch2' - raw_id = 'deadbeef0123456789' + repo.name = "abcde" + full_repo_name = "test-repo-group/" + repo.name + ref_name = "branch1/branch2" + raw_id = "deadbeef0123456789" is_svn = False - with mock.patch('rhodecode.lib.helpers.route_path') as url_mock: - result = summary_view._create_files_url( - repo, full_repo_name, ref_name, raw_id, is_svn) + with mock.patch("rhodecode.lib.helpers.route_path") as url_mock: + result = summary_view._create_files_url(repo, full_repo_name, ref_name, raw_id, is_svn) url_mock.assert_called_once_with( - 'repo_files', repo_name=full_repo_name, commit_id=raw_id, - f_path='', _query=dict(at=ref_name)) + "repo_files", repo_name=full_repo_name, commit_id=raw_id, f_path="", _query=dict(at=ref_name) + ) assert result == url_mock.return_value class TestReferenceItems(object): repo = mock.Mock() - repo.name = 'pytest-repo' - repo_full_name = 'pytest-repo-group/' + repo.name - ref_type = 'branch' - fake_url = '/abcde/' + repo.name = "pytest-repo" + repo_full_name = "pytest-repo-group/" + repo.name + ref_type = "branch" + fake_url = "/abcde/" @staticmethod def _format_function(name, id_): - return 'format_function_{}_{}'.format(name, id_) + return "format_function_{}_{}".format(name, id_) def test_creates_required_amount_of_items(self, summary_view): amount = 100 - refs = { - 'ref{}'.format(i): '{0:040d}'.format(i) - for i in range(amount) - } + refs = {"ref{}".format(i): "{0:040d}".format(i) for i in range(amount)} - url_patcher = mock.patch.object(summary_view, '_create_files_url') - svn_patcher = mock.patch('rhodecode.lib.helpers.is_svn', - return_value=False) + url_patcher = mock.patch.object(summary_view, "_create_files_url") + svn_patcher = mock.patch("rhodecode.lib.helpers.is_svn", return_value=False) with url_patcher as url_mock, svn_patcher: result = summary_view._create_reference_items( - self.repo, self.repo_full_name, refs, self.ref_type, - self._format_function) + self.repo, self.repo_full_name, refs, self.ref_type, self._format_function + ) assert len(result) == amount assert url_mock.call_count == amount def test_single_item_details(self, summary_view): - ref_name = 'ref1' - ref_id = 'deadbeef' - refs = { - ref_name: ref_id - } + ref_name = "ref1" + ref_id = "deadbeef" + refs = {ref_name: ref_id} - svn_patcher = mock.patch('rhodecode.lib.helpers.is_svn', - return_value=False) + svn_patcher = mock.patch("rhodecode.lib.helpers.is_svn", return_value=False) - url_patcher = mock.patch.object( - summary_view, '_create_files_url', return_value=self.fake_url) + url_patcher = mock.patch.object(summary_view, "_create_files_url", return_value=self.fake_url) with url_patcher as url_mock, svn_patcher: result = summary_view._create_reference_items( - self.repo, self.repo_full_name, refs, self.ref_type, - self._format_function) + self.repo, self.repo_full_name, refs, self.ref_type, self._format_function + ) - url_mock.assert_called_once_with( - self.repo, self.repo_full_name, ref_name, ref_id, False) + url_mock.assert_called_once_with(self.repo, self.repo_full_name, ref_name, ref_id, False) expected_result = [ { - 'text': ref_name, - 'id': self._format_function(ref_name, ref_id), - 'raw_id': ref_id, - 'idx': 0, - 'type': self.ref_type, - 'files_url': self.fake_url + "text": ref_name, + "id": self._format_function(ref_name, ref_id), + "raw_id": ref_id, + "idx": 0, + "type": self.ref_type, + "files_url": self.fake_url, } ] assert result == expected_result diff --git a/rhodecode/apps/repository/tests/test_repo_tags.py b/rhodecode/apps/repository/tests/test_repo_tags.py index 02ebce38..2522da2f 100644 --- a/rhodecode/apps/repository/tests/test_repo_tags.py +++ b/rhodecode/apps/repository/tests/test_repo_tags.py @@ -21,11 +21,10 @@ from rhodecode.model.db import Repository from rhodecode.tests.routes import route_path -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestTagsController(object): def test_index(self, backend): - response = self.app.get( - route_path('tags_home', repo_name=backend.repo_name)) + response = self.app.get(route_path("tags_home", repo_name=backend.repo_name)) repo = Repository.get_by_repo_name(backend.repo_name) diff --git a/rhodecode/apps/repository/tests/test_repo_vcs_settings.py b/rhodecode/apps/repository/tests/test_repo_vcs_settings.py index 2e5307f4..c984d3cf 100644 --- a/rhodecode/apps/repository/tests/test_repo_vcs_settings.py +++ b/rhodecode/apps/repository/tests/test_repo_vcs_settings.py @@ -21,14 +21,11 @@ import pytest from rhodecode.lib import auth from rhodecode.lib.utils2 import str2bool -from rhodecode.model.db import ( - Repository, UserRepoToPerm, User) +from rhodecode.model.db import Repository, UserRepoToPerm, User from rhodecode.model.meta import Session from rhodecode.model.settings import SettingsModel, VcsSettingsModel from rhodecode.model.user import UserModel -from rhodecode.tests import ( - login_user_session, logout_user_session, - TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) +from rhodecode.tests import login_user_session, logout_user_session, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.utils import AssertResponse from rhodecode.tests.routes import route_path @@ -39,73 +36,69 @@ fixture = Fixture() @pytest.mark.usefixtures("app") class TestVcsSettings(object): FORM_DATA = { - 'inherit_global_settings': False, - 'hooks_changegroup_repo_size': False, - 'hooks_changegroup_push_logger': False, - 'hooks_outgoing_pull_logger': False, - 'extensions_largefiles': False, - 'extensions_evolve': False, - 'phases_publish': 'False', - 'rhodecode_pr_merge_enabled': False, - 'rhodecode_auto_merge_enabled': False, - 'rhodecode_use_outdated_comments': False, - 'new_svn_branch': '', - 'new_svn_tag': '' + "inherit_global_settings": False, + "hooks_changegroup_repo_size": False, + "hooks_changegroup_push_logger": False, + "hooks_outgoing_pull_logger": False, + "extensions_largefiles": False, + "extensions_evolve": False, + "phases_publish": "False", + "rhodecode_pr_merge_enabled": False, + "rhodecode_auto_merge_enabled": False, + "rhodecode_use_outdated_comments": False, + "new_svn_branch": "", + "new_svn_tag": "", } - @pytest.mark.skip_backends('svn') + @pytest.mark.skip_backends("svn") def test_global_settings_initial_values(self, autologin_user, backend): repo_name = backend.repo_name - response = self.app.get(route_path('edit_repo_vcs', repo_name=repo_name)) + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name)) expected_settings = ( - 'rhodecode_use_outdated_comments', 'rhodecode_pr_merge_enabled', 'rhodecode_auto_merge_enabled', - 'hooks_changegroup_repo_size', 'hooks_changegroup_push_logger', - 'hooks_outgoing_pull_logger' + "rhodecode_use_outdated_comments", + "rhodecode_pr_merge_enabled", + "rhodecode_auto_merge_enabled", + "hooks_changegroup_repo_size", + "hooks_changegroup_push_logger", + "hooks_outgoing_pull_logger", ) for setting in expected_settings: self.assert_repo_value_equals_global_value(response, setting) - def test_show_settings_requires_repo_admin_permission( - self, backend, user_util, settings_util): + def test_show_settings_requires_repo_admin_permission(self, backend, user_util, settings_util): repo = backend.create_repo() repo_name = repo.repo_name user = UserModel().get_by_username(TEST_USER_REGULAR_LOGIN) - user_util.grant_user_permission_to_repo(repo, user, 'repository.admin') - login_user_session( - self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - self.app.get(route_path('edit_repo_vcs', repo_name=repo_name), status=200) + user_util.grant_user_permission_to_repo(repo, user, "repository.admin") + login_user_session(self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + self.app.get(route_path("edit_repo_vcs", repo_name=repo_name), status=200) - def test_inherit_global_settings_flag_is_true_by_default( - self, autologin_user, backend): + def test_inherit_global_settings_flag_is_true_by_default(self, autologin_user, backend): repo_name = backend.repo_name - response = self.app.get(route_path('edit_repo_vcs', repo_name=repo_name)) + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name)) assert_response = response.assert_response() - element = assert_response.get_element('#inherit_global_settings') + element = assert_response.get_element("#inherit_global_settings") assert element.checked - @pytest.mark.parametrize('checked_value', [True, False]) - def test_inherit_global_settings_value( - self, autologin_user, backend, checked_value, settings_util): + @pytest.mark.parametrize("checked_value", [True, False]) + def test_inherit_global_settings_value(self, autologin_user, backend, checked_value, settings_util): repo = backend.create_repo() repo_name = repo.repo_name - settings_util.create_repo_rhodecode_setting( - repo, 'inherit_vcs_settings', checked_value, 'bool') - response = self.app.get(route_path('edit_repo_vcs', repo_name=repo_name)) + settings_util.create_repo_rhodecode_setting(repo, "inherit_vcs_settings", checked_value, "bool") + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name)) assert_response = response.assert_response() - element = assert_response.get_element('#inherit_global_settings') + element = assert_response.get_element("#inherit_global_settings") assert element.checked == checked_value - @pytest.mark.skip_backends('svn') - def test_hooks_settings_are_created( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("svn") + def test_hooks_settings_are_created(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: for section, key in VcsSettingsModel.HOOKS_SETTINGS: @@ -114,13 +107,11 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - def test_hooks_settings_are_not_created_for_svn( - self, autologin_user, backend_svn, csrf_token): + def test_hooks_settings_are_not_created_for_svn(self, autologin_user, backend_svn, csrf_token): repo_name = backend_svn.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: for section, key in VcsSettingsModel.HOOKS_SETTINGS: @@ -129,18 +120,16 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - @pytest.mark.skip_backends('svn') - def test_hooks_settings_are_updated( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("svn") + def test_hooks_settings_are_updated(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name settings = SettingsModel(repo=repo_name) for section, key in VcsSettingsModel.HOOKS_SETTINGS: - settings.create_ui_section_value(section, '', key=key, active=True) + settings.create_ui_section_value(section, "", key=key, active=True) data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) try: for section, key in VcsSettingsModel.HOOKS_SETTINGS: ui = settings.get_ui_by_section_and_key(section, key) @@ -148,17 +137,15 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - def test_hooks_settings_are_not_updated_for_svn( - self, autologin_user, backend_svn, csrf_token): + def test_hooks_settings_are_not_updated_for_svn(self, autologin_user, backend_svn, csrf_token): repo_name = backend_svn.repo_name settings = SettingsModel(repo=repo_name) for section, key in VcsSettingsModel.HOOKS_SETTINGS: - settings.create_ui_section_value(section, '', key=key, active=True) + settings.create_ui_section_value(section, "", key=key, active=True) data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) try: for section, key in VcsSettingsModel.HOOKS_SETTINGS: ui = settings.get_ui_by_section_and_key(section, key) @@ -166,14 +153,12 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - @pytest.mark.skip_backends('svn') - def test_pr_settings_are_created( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("svn") + def test_pr_settings_are_created(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: for name in VcsSettingsModel.GENERAL_SETTINGS: @@ -182,13 +167,11 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - def test_pr_settings_are_not_created_for_svn( - self, autologin_user, backend_svn, csrf_token): + def test_pr_settings_are_not_created_for_svn(self, autologin_user, backend_svn, csrf_token): repo_name = backend_svn.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: for name in VcsSettingsModel.GENERAL_SETTINGS: @@ -197,42 +180,36 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - def test_pr_settings_creation_requires_repo_admin_permission( - self, backend, user_util, settings_util, csrf_token): + def test_pr_settings_creation_requires_repo_admin_permission(self, backend, user_util, settings_util, csrf_token): repo = backend.create_repo() repo_name = repo.repo_name logout_user_session(self.app, csrf_token) - session = login_user_session( - self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + session = login_user_session(self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) new_csrf_token = auth.get_csrf_token(session) user = UserModel().get_by_username(TEST_USER_REGULAR_LOGIN) repo = Repository.get_by_repo_name(repo_name) - user_util.grant_user_permission_to_repo(repo, user, 'repository.admin') + user_util.grant_user_permission_to_repo(repo, user, "repository.admin") data = self.FORM_DATA.copy() - data['csrf_token'] = new_csrf_token + data["csrf_token"] = new_csrf_token settings = SettingsModel(repo=repo_name) try: - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, - status=302) + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) finally: self._cleanup_repo_settings(settings) - @pytest.mark.skip_backends('svn') - def test_pr_settings_are_updated( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("svn") + def test_pr_settings_are_updated(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name settings = SettingsModel(repo=repo_name) for name in VcsSettingsModel.GENERAL_SETTINGS: - settings.create_or_update_setting(name, True, 'bool') + settings.create_or_update_setting(name, True, "bool") data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) try: for name in VcsSettingsModel.GENERAL_SETTINGS: setting = settings.get_setting_by_name(name) @@ -240,17 +217,15 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - def test_pr_settings_are_not_updated_for_svn( - self, autologin_user, backend_svn, csrf_token): + def test_pr_settings_are_not_updated_for_svn(self, autologin_user, backend_svn, csrf_token): repo_name = backend_svn.repo_name settings = SettingsModel(repo=repo_name) for name in VcsSettingsModel.GENERAL_SETTINGS: - settings.create_or_update_setting(name, True, 'bool') + settings.create_or_update_setting(name, True, "bool") data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) try: for name in VcsSettingsModel.GENERAL_SETTINGS: setting = settings.get_setting_by_name(name) @@ -258,249 +233,196 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - def test_svn_settings_are_created( - self, autologin_user, backend_svn, csrf_token, settings_util): + def test_svn_settings_are_created(self, autologin_user, backend_svn, csrf_token, settings_util): repo_name = backend_svn.repo_name data = self.FORM_DATA.copy() - data['new_svn_tag'] = 'svn-tag' - data['new_svn_branch'] = 'svn-branch' - data['csrf_token'] = csrf_token + data["new_svn_tag"] = "svn-tag" + data["new_svn_branch"] = "svn-branch" + data["csrf_token"] = csrf_token # Create few global settings to make sure that uniqueness validators # are not triggered - settings_util.create_rhodecode_ui( - VcsSettingsModel.SVN_BRANCH_SECTION, 'svn-branch') - settings_util.create_rhodecode_ui( - VcsSettingsModel.SVN_TAG_SECTION, 'svn-tag') + settings_util.create_rhodecode_ui(VcsSettingsModel.SVN_BRANCH_SECTION, "svn-branch") + settings_util.create_rhodecode_ui(VcsSettingsModel.SVN_TAG_SECTION, "svn-tag") - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: - svn_branches = settings.get_ui_by_section( - VcsSettingsModel.SVN_BRANCH_SECTION) + svn_branches = settings.get_ui_by_section(VcsSettingsModel.SVN_BRANCH_SECTION) svn_branch_names = [b.ui_value for b in svn_branches] - svn_tags = settings.get_ui_by_section( - VcsSettingsModel.SVN_TAG_SECTION) + svn_tags = settings.get_ui_by_section(VcsSettingsModel.SVN_TAG_SECTION) svn_tag_names = [b.ui_value for b in svn_tags] - assert 'svn-branch' in svn_branch_names - assert 'svn-tag' in svn_tag_names + assert "svn-branch" in svn_branch_names + assert "svn-tag" in svn_tag_names finally: self._cleanup_repo_settings(settings) - def test_svn_settings_are_unique( - self, autologin_user, backend_svn, csrf_token, settings_util): + def test_svn_settings_are_unique(self, autologin_user, backend_svn, csrf_token, settings_util): repo = backend_svn.repo repo_name = repo.repo_name data = self.FORM_DATA.copy() - data['new_svn_tag'] = 'test_tag' - data['new_svn_branch'] = 'test_branch' - data['csrf_token'] = csrf_token - settings_util.create_repo_rhodecode_ui( - repo, VcsSettingsModel.SVN_BRANCH_SECTION, 'test_branch') - settings_util.create_repo_rhodecode_ui( - repo, VcsSettingsModel.SVN_TAG_SECTION, 'test_tag') + data["new_svn_tag"] = "test_tag" + data["new_svn_branch"] = "test_branch" + data["csrf_token"] = csrf_token + settings_util.create_repo_rhodecode_ui(repo, VcsSettingsModel.SVN_BRANCH_SECTION, "test_branch") + settings_util.create_repo_rhodecode_ui(repo, VcsSettingsModel.SVN_TAG_SECTION, "test_tag") - response = self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=200) - response.mustcontain('Pattern already exists') + response = self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=200) + response.mustcontain("Pattern already exists") - def test_svn_settings_with_empty_values_are_not_created( - self, autologin_user, backend_svn, csrf_token): + def test_svn_settings_with_empty_values_are_not_created(self, autologin_user, backend_svn, csrf_token): repo_name = backend_svn.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: - svn_branches = settings.get_ui_by_section( - VcsSettingsModel.SVN_BRANCH_SECTION) - svn_tags = settings.get_ui_by_section( - VcsSettingsModel.SVN_TAG_SECTION) + svn_branches = settings.get_ui_by_section(VcsSettingsModel.SVN_BRANCH_SECTION) + svn_tags = settings.get_ui_by_section(VcsSettingsModel.SVN_TAG_SECTION) assert len(svn_branches) == 0 assert len(svn_tags) == 0 finally: self._cleanup_repo_settings(settings) - def test_svn_settings_are_shown_for_svn_repository( - self, autologin_user, backend_svn, csrf_token): + def test_svn_settings_are_shown_for_svn_repository(self, autologin_user, backend_svn, csrf_token): repo_name = backend_svn.repo_name - response = self.app.get( - route_path('edit_repo_vcs', repo_name=repo_name), status=200) - response.mustcontain('Subversion Settings') + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name), status=200) + response.mustcontain("Subversion Settings") - @pytest.mark.skip_backends('svn') - def test_svn_settings_are_not_created_for_not_svn_repository( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("svn") + def test_svn_settings_are_not_created_for_not_svn_repository(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: - svn_branches = settings.get_ui_by_section( - VcsSettingsModel.SVN_BRANCH_SECTION) - svn_tags = settings.get_ui_by_section( - VcsSettingsModel.SVN_TAG_SECTION) + svn_branches = settings.get_ui_by_section(VcsSettingsModel.SVN_BRANCH_SECTION) + svn_tags = settings.get_ui_by_section(VcsSettingsModel.SVN_TAG_SECTION) assert len(svn_branches) == 0 assert len(svn_tags) == 0 finally: self._cleanup_repo_settings(settings) - @pytest.mark.skip_backends('svn') - def test_svn_settings_are_shown_only_for_svn_repository( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("svn") + def test_svn_settings_are_shown_only_for_svn_repository(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name - response = self.app.get( - route_path('edit_repo_vcs', repo_name=repo_name), status=200) - response.mustcontain(no='Subversion Settings') + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name), status=200) + response.mustcontain(no="Subversion Settings") - def test_hg_settings_are_created( - self, autologin_user, backend_hg, csrf_token): + def test_hg_settings_are_created(self, autologin_user, backend_hg, csrf_token): repo_name = backend_hg.repo_name data = self.FORM_DATA.copy() - data['new_svn_tag'] = 'svn-tag' - data['new_svn_branch'] = 'svn-branch' - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["new_svn_tag"] = "svn-tag" + data["new_svn_branch"] = "svn-branch" + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: - largefiles_ui = settings.get_ui_by_section_and_key( - 'extensions', 'largefiles') + largefiles_ui = settings.get_ui_by_section_and_key("extensions", "largefiles") assert largefiles_ui.ui_active is False - phases_ui = settings.get_ui_by_section_and_key( - 'phases', 'publish') + phases_ui = settings.get_ui_by_section_and_key("phases", "publish") assert str2bool(phases_ui.ui_value) is False finally: self._cleanup_repo_settings(settings) - def test_hg_settings_are_updated( - self, autologin_user, backend_hg, csrf_token): + def test_hg_settings_are_updated(self, autologin_user, backend_hg, csrf_token): repo_name = backend_hg.repo_name settings = SettingsModel(repo=repo_name) - settings.create_ui_section_value( - 'extensions', '', key='largefiles', active=True) - settings.create_ui_section_value( - 'phases', '1', key='publish', active=True) + settings.create_ui_section_value("extensions", "", key="largefiles", active=True) + settings.create_ui_section_value("phases", "1", key="publish", active=True) data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) try: - largefiles_ui = settings.get_ui_by_section_and_key( - 'extensions', 'largefiles') + largefiles_ui = settings.get_ui_by_section_and_key("extensions", "largefiles") assert largefiles_ui.ui_active is False - phases_ui = settings.get_ui_by_section_and_key( - 'phases', 'publish') + phases_ui = settings.get_ui_by_section_and_key("phases", "publish") assert str2bool(phases_ui.ui_value) is False finally: self._cleanup_repo_settings(settings) - def test_hg_settings_are_shown_for_hg_repository( - self, autologin_user, backend_hg, csrf_token): + def test_hg_settings_are_shown_for_hg_repository(self, autologin_user, backend_hg, csrf_token): repo_name = backend_hg.repo_name - response = self.app.get( - route_path('edit_repo_vcs', repo_name=repo_name), status=200) - response.mustcontain('Mercurial Settings') + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name), status=200) + response.mustcontain("Mercurial Settings") - @pytest.mark.skip_backends('hg') - def test_hg_settings_are_created_only_for_hg_repository( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("hg") + def test_hg_settings_are_created_only_for_hg_repository(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) try: - largefiles_ui = settings.get_ui_by_section_and_key( - 'extensions', 'largefiles') + largefiles_ui = settings.get_ui_by_section_and_key("extensions", "largefiles") assert largefiles_ui is None - phases_ui = settings.get_ui_by_section_and_key( - 'phases', 'publish') + phases_ui = settings.get_ui_by_section_and_key("phases", "publish") assert phases_ui is None finally: self._cleanup_repo_settings(settings) - @pytest.mark.skip_backends('hg') - def test_hg_settings_are_shown_only_for_hg_repository( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("hg") + def test_hg_settings_are_shown_only_for_hg_repository(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name - response = self.app.get( - route_path('edit_repo_vcs', repo_name=repo_name), status=200) - response.mustcontain(no='Mercurial Settings') + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name), status=200) + response.mustcontain(no="Mercurial Settings") - @pytest.mark.skip_backends('hg') - def test_hg_settings_are_updated_only_for_hg_repository( - self, autologin_user, backend, csrf_token): + @pytest.mark.skip_backends("hg") + def test_hg_settings_are_updated_only_for_hg_repository(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name settings = SettingsModel(repo=repo_name) - settings.create_ui_section_value( - 'extensions', '', key='largefiles', active=True) - settings.create_ui_section_value( - 'phases', '1', key='publish', active=True) + settings.create_ui_section_value("extensions", "", key="largefiles", active=True) + settings.create_ui_section_value("phases", "1", key="publish", active=True) data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) try: - largefiles_ui = settings.get_ui_by_section_and_key( - 'extensions', 'largefiles') + largefiles_ui = settings.get_ui_by_section_and_key("extensions", "largefiles") assert largefiles_ui.ui_active is True - phases_ui = settings.get_ui_by_section_and_key( - 'phases', 'publish') - assert phases_ui.ui_value == '1' + phases_ui = settings.get_ui_by_section_and_key("phases", "publish") + assert phases_ui.ui_value == "1" finally: self._cleanup_repo_settings(settings) - def test_per_repo_svn_settings_are_displayed( - self, autologin_user, backend_svn, settings_util): + def test_per_repo_svn_settings_are_displayed(self, autologin_user, backend_svn, settings_util): repo = backend_svn.create_repo() repo_name = repo.repo_name branches = [ - settings_util.create_repo_rhodecode_ui( - repo, VcsSettingsModel.SVN_BRANCH_SECTION, - 'branch_{}'.format(i)) - for i in range(10)] + settings_util.create_repo_rhodecode_ui(repo, VcsSettingsModel.SVN_BRANCH_SECTION, "branch_{}".format(i)) + for i in range(10) + ] tags = [ - settings_util.create_repo_rhodecode_ui( - repo, VcsSettingsModel.SVN_TAG_SECTION, 'tag_{}'.format(i)) - for i in range(10)] + settings_util.create_repo_rhodecode_ui(repo, VcsSettingsModel.SVN_TAG_SECTION, "tag_{}".format(i)) + for i in range(10) + ] - response = self.app.get( - route_path('edit_repo_vcs', repo_name=repo_name), status=200) + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name), status=200) assert_response = response.assert_response() for branch in branches: - css_selector = '[name=branch_value_{}]'.format(branch.ui_id) + css_selector = "[name=branch_value_{}]".format(branch.ui_id) element = assert_response.get_element(css_selector) assert element.value == branch.ui_value for tag in tags: - css_selector = '[name=tag_ui_value_new_{}]'.format(tag.ui_id) + css_selector = "[name=tag_ui_value_new_{}]".format(tag.ui_id) element = assert_response.get_element(css_selector) assert element.value == tag.ui_value - def test_per_repo_hg_and_pr_settings_are_not_displayed_for_svn( - self, autologin_user, backend_svn, settings_util): + def test_per_repo_hg_and_pr_settings_are_not_displayed_for_svn(self, autologin_user, backend_svn, settings_util): repo = backend_svn.create_repo() repo_name = repo.repo_name - response = self.app.get( - route_path('edit_repo_vcs', repo_name=repo_name), status=200) - response.mustcontain(no='') - response.mustcontain(no='') + response = self.app.get(route_path("edit_repo_vcs", repo_name=repo_name), status=200) + response.mustcontain(no="") + response.mustcontain(no="") - def test_inherit_global_settings_value_is_saved( - self, autologin_user, backend, csrf_token): + def test_inherit_global_settings_value_is_saved(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - data['inherit_global_settings'] = True - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + data["inherit_global_settings"] = True + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) vcs_settings = VcsSettingsModel(repo=repo_name) @@ -509,37 +431,30 @@ class TestVcsSettings(object): finally: self._cleanup_repo_settings(settings) - def test_repo_cache_is_invalidated_when_settings_are_updated( - self, autologin_user, backend, csrf_token): + def test_repo_cache_is_invalidated_when_settings_are_updated(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - data['inherit_global_settings'] = True + data["csrf_token"] = csrf_token + data["inherit_global_settings"] = True settings = SettingsModel(repo=repo_name) - invalidation_patcher = mock.patch( - 'rhodecode.model.scm.ScmModel.mark_for_invalidation') + invalidation_patcher = mock.patch("rhodecode.model.scm.ScmModel.mark_for_invalidation") with invalidation_patcher as invalidation_mock: - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, - status=302) + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) try: invalidation_mock.assert_called_once_with(repo_name, delete=True) finally: self._cleanup_repo_settings(settings) - def test_other_settings_not_saved_inherit_global_settings_is_true( - self, autologin_user, backend, csrf_token): + def test_other_settings_not_saved_inherit_global_settings_is_true(self, autologin_user, backend, csrf_token): repo_name = backend.repo_name data = self.FORM_DATA.copy() - data['csrf_token'] = csrf_token - data['inherit_global_settings'] = True - self.app.post( - route_path('edit_repo_vcs_update', repo_name=repo_name), data, status=302) + data["csrf_token"] = csrf_token + data["inherit_global_settings"] = True + self.app.post(route_path("edit_repo_vcs_update", repo_name=repo_name), data, status=302) settings = SettingsModel(repo=repo_name) - ui_settings = ( - VcsSettingsModel.HOOKS_SETTINGS + VcsSettingsModel.HG_SETTINGS) + ui_settings = VcsSettingsModel.HOOKS_SETTINGS + VcsSettingsModel.HG_SETTINGS vcs_settings = [] try: @@ -547,10 +462,8 @@ class TestVcsSettings(object): ui = settings.get_ui_by_section_and_key(section, key) if ui: vcs_settings.append(ui) - vcs_settings.extend(settings.get_ui_by_section( - VcsSettingsModel.SVN_BRANCH_SECTION)) - vcs_settings.extend(settings.get_ui_by_section( - VcsSettingsModel.SVN_TAG_SECTION)) + vcs_settings.extend(settings.get_ui_by_section(VcsSettingsModel.SVN_BRANCH_SECTION)) + vcs_settings.extend(settings.get_ui_by_section(VcsSettingsModel.SVN_TAG_SECTION)) for name in VcsSettingsModel.GENERAL_SETTINGS: setting = settings.get_setting_by_name(name) if setting: @@ -560,86 +473,86 @@ class TestVcsSettings(object): self._cleanup_repo_settings(settings) def test_delete_svn_branch_and_tag_patterns( - self, autologin_user, backend_svn, settings_util, csrf_token, xhr_header): + self, autologin_user, backend_svn, settings_util, csrf_token, xhr_header + ): repo = backend_svn.create_repo() repo_name = repo.repo_name branch = settings_util.create_repo_rhodecode_ui( - repo, VcsSettingsModel.SVN_BRANCH_SECTION, 'test_branch', - cleanup=False) - tag = settings_util.create_repo_rhodecode_ui( - repo, VcsSettingsModel.SVN_TAG_SECTION, 'test_tag', cleanup=False) - data = { - 'csrf_token': csrf_token - } + repo, VcsSettingsModel.SVN_BRANCH_SECTION, "test_branch", cleanup=False + ) + tag = settings_util.create_repo_rhodecode_ui(repo, VcsSettingsModel.SVN_TAG_SECTION, "test_tag", cleanup=False) + data = {"csrf_token": csrf_token} for id_ in (branch.ui_id, tag.ui_id): - data['delete_svn_pattern'] = id_, + data["delete_svn_pattern"] = (id_,) self.app.post( - route_path('edit_repo_vcs_svn_pattern_delete', repo_name=repo_name), - data, extra_environ=xhr_header, status=200) + route_path("edit_repo_vcs_svn_pattern_delete", repo_name=repo_name), + data, + extra_environ=xhr_header, + status=200, + ) settings = VcsSettingsModel(repo=repo_name) assert settings.get_repo_svn_branch_patterns() == [] def test_delete_svn_branch_requires_repo_admin_permission( - self, backend_svn, user_util, settings_util, csrf_token, xhr_header): + self, backend_svn, user_util, settings_util, csrf_token, xhr_header + ): repo = backend_svn.create_repo() repo_name = repo.repo_name logout_user_session(self.app, csrf_token) - session = login_user_session( - self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + session = login_user_session(self.app, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) csrf_token = auth.get_csrf_token(session) repo = Repository.get_by_repo_name(repo_name) user = UserModel().get_by_username(TEST_USER_REGULAR_LOGIN) - user_util.grant_user_permission_to_repo(repo, user, 'repository.admin') + user_util.grant_user_permission_to_repo(repo, user, "repository.admin") branch = settings_util.create_repo_rhodecode_ui( - repo, VcsSettingsModel.SVN_BRANCH_SECTION, 'test_branch', - cleanup=False) - data = { - 'csrf_token': csrf_token, - 'delete_svn_pattern': branch.ui_id - } + repo, VcsSettingsModel.SVN_BRANCH_SECTION, "test_branch", cleanup=False + ) + data = {"csrf_token": csrf_token, "delete_svn_pattern": branch.ui_id} self.app.post( - route_path('edit_repo_vcs_svn_pattern_delete', repo_name=repo_name), - data, extra_environ=xhr_header, status=200) + route_path("edit_repo_vcs_svn_pattern_delete", repo_name=repo_name), + data, + extra_environ=xhr_header, + status=200, + ) def test_delete_svn_branch_raises_400_when_not_found( - self, autologin_user, backend_svn, settings_util, csrf_token, xhr_header): + self, autologin_user, backend_svn, settings_util, csrf_token, xhr_header + ): repo_name = backend_svn.repo_name - data = { - 'delete_svn_pattern': 123, - 'csrf_token': csrf_token - } + data = {"delete_svn_pattern": 123, "csrf_token": csrf_token} self.app.post( - route_path('edit_repo_vcs_svn_pattern_delete', repo_name=repo_name), - data, extra_environ=xhr_header, status=400) + route_path("edit_repo_vcs_svn_pattern_delete", repo_name=repo_name), + data, + extra_environ=xhr_header, + status=400, + ) def test_delete_svn_branch_raises_400_when_no_id_specified( - self, autologin_user, backend_svn, settings_util, csrf_token, xhr_header): + self, autologin_user, backend_svn, settings_util, csrf_token, xhr_header + ): repo_name = backend_svn.repo_name - data = { - 'csrf_token': csrf_token - } + data = {"csrf_token": csrf_token} self.app.post( - route_path('edit_repo_vcs_svn_pattern_delete', repo_name=repo_name), - data, extra_environ=xhr_header, status=400) + route_path("edit_repo_vcs_svn_pattern_delete", repo_name=repo_name), + data, + extra_environ=xhr_header, + status=400, + ) def _cleanup_repo_settings(self, settings_model): cleanup = [] - ui_settings = ( - VcsSettingsModel.HOOKS_SETTINGS + VcsSettingsModel.HG_SETTINGS) + ui_settings = VcsSettingsModel.HOOKS_SETTINGS + VcsSettingsModel.HG_SETTINGS for section, key in ui_settings: ui = settings_model.get_ui_by_section_and_key(section, key) if ui: cleanup.append(ui) - cleanup.extend(settings_model.get_ui_by_section( - VcsSettingsModel.INHERIT_SETTINGS)) - cleanup.extend(settings_model.get_ui_by_section( - VcsSettingsModel.SVN_BRANCH_SECTION)) - cleanup.extend(settings_model.get_ui_by_section( - VcsSettingsModel.SVN_TAG_SECTION)) + cleanup.extend(settings_model.get_ui_by_section(VcsSettingsModel.INHERIT_SETTINGS)) + cleanup.extend(settings_model.get_ui_by_section(VcsSettingsModel.SVN_BRANCH_SECTION)) + cleanup.extend(settings_model.get_ui_by_section(VcsSettingsModel.SVN_TAG_SECTION)) for name in VcsSettingsModel.GENERAL_SETTINGS: setting = settings_model.get_setting_by_name(name) @@ -652,17 +565,18 @@ class TestVcsSettings(object): def assert_repo_value_equals_global_value(self, response, setting): assert_response = response.assert_response() - global_css_selector = '[name={}_inherited]'.format(setting) - repo_css_selector = '[name={}]'.format(setting) + global_css_selector = "[name={}_inherited]".format(setting) + repo_css_selector = "[name={}]".format(setting) repo_element = assert_response.get_element(repo_css_selector) global_element = assert_response.get_element(global_css_selector) assert repo_element.value == global_element.value def _get_permission_for_user(user, repo): - perm = UserRepoToPerm.query()\ - .filter(UserRepoToPerm.repository == - Repository.get_by_repo_name(repo))\ - .filter(UserRepoToPerm.user == User.get_by_username(user))\ + perm = ( + UserRepoToPerm.query() + .filter(UserRepoToPerm.repository == Repository.get_by_repo_name(repo)) + .filter(UserRepoToPerm.user == User.get_by_username(user)) .all() + ) return perm diff --git a/rhodecode/apps/repository/tests/test_vcs_settings.py b/rhodecode/apps/repository/tests/test_vcs_settings.py index edb136d4..e1b9e766 100644 --- a/rhodecode/apps/repository/tests/test_vcs_settings.py +++ b/rhodecode/apps/repository/tests/test_vcs_settings.py @@ -25,48 +25,52 @@ from rhodecode.model.settings import SettingsModel from rhodecode.tests.routes import route_path -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAdminRepoVcsSettings(object): - - @pytest.mark.parametrize('setting_name, setting_backends', [ - ('hg_use_rebase_for_merging', ['hg']), - ]) + @pytest.mark.parametrize( + "setting_name, setting_backends", + [ + ("hg_use_rebase_for_merging", ["hg"]), + ], + ) def test_labs_settings_visible_if_enabled(self, setting_name, setting_backends, backend): if backend.alias not in setting_backends: - pytest.skip('Setting not available for backend {}'.format(backend)) + pytest.skip("Setting not available for backend {}".format(backend)) - vcs_settings_url = route_path('edit_repo_vcs', repo_name=backend.repo.repo_name) + vcs_settings_url = route_path("edit_repo_vcs", repo_name=backend.repo.repo_name) - with mock.patch.dict(rhodecode.CONFIG, {'labs_settings_active': 'true'}): + with mock.patch.dict(rhodecode.CONFIG, {"labs_settings_active": "true"}): response = self.app.get(vcs_settings_url) assertr = response.assert_response() - assertr.one_element_exists('#rhodecode_{}'.format(setting_name)) + assertr.one_element_exists("#rhodecode_{}".format(setting_name)) - @pytest.mark.parametrize('setting_name, setting_backends', [ - ('hg_use_rebase_for_merging', ['hg']), - ]) - def test_update_boolean_settings( - self, csrf_token, setting_name, setting_backends, backend): + @pytest.mark.parametrize( + "setting_name, setting_backends", + [ + ("hg_use_rebase_for_merging", ["hg"]), + ], + ) + def test_update_boolean_settings(self, csrf_token, setting_name, setting_backends, backend): if backend.alias not in setting_backends: - pytest.skip('Setting not available for backend {}'.format(backend)) + pytest.skip("Setting not available for backend {}".format(backend)) repo = backend.create_repo() repo_name = repo.repo_name settings_model = SettingsModel(repo=repo) - vcs_settings_url = route_path( - 'edit_repo_vcs_update', repo_name=repo_name) + vcs_settings_url = route_path("edit_repo_vcs_update", repo_name=repo_name) self.app.post( vcs_settings_url, params={ - 'inherit_global_settings': False, - 'new_svn_branch': 'dummy-value-for-testing', - 'new_svn_tag': 'dummy-value-for-testing', - 'rhodecode_{}'.format(setting_name): 'true', - 'csrf_token': csrf_token, - }) + "inherit_global_settings": False, + "new_svn_branch": "dummy-value-for-testing", + "new_svn_tag": "dummy-value-for-testing", + "rhodecode_{}".format(setting_name): "true", + "csrf_token": csrf_token, + }, + ) settings_model = SettingsModel(repo=Repository.get_by_repo_name(repo_name)) setting = settings_model.get_setting_by_name(setting_name) assert setting.app_settings_value @@ -74,12 +78,13 @@ class TestAdminRepoVcsSettings(object): self.app.post( vcs_settings_url, params={ - 'inherit_global_settings': False, - 'new_svn_branch': 'dummy-value-for-testing', - 'new_svn_tag': 'dummy-value-for-testing', - 'rhodecode_{}'.format(setting_name): 'false', - 'csrf_token': csrf_token, - }) + "inherit_global_settings": False, + "new_svn_branch": "dummy-value-for-testing", + "new_svn_tag": "dummy-value-for-testing", + "rhodecode_{}".format(setting_name): "false", + "csrf_token": csrf_token, + }, + ) settings_model = SettingsModel(repo=Repository.get_by_repo_name(repo_name)) setting = settings_model.get_setting_by_name(setting_name) assert not setting.app_settings_value diff --git a/rhodecode/apps/repository/utils.py b/rhodecode/apps/repository/utils.py index 08034a39..4ed3af51 100644 --- a/rhodecode/apps/repository/utils.py +++ b/rhodecode/apps/repository/utils.py @@ -20,10 +20,11 @@ from rhodecode.lib import helpers as h, rc_cache from rhodecode.lib.utils2 import safe_int from rhodecode.model.pull_request import get_diff_info from rhodecode.model.db import PullRequestReviewers + # V3 - Reviewers, with default rules data # v4 - Added observers metadata # v5 - pr_author/commit_author include/exclude logic -REVIEWER_API_VERSION = 'V5' +REVIEWER_API_VERSION = "V5" def reviewer_as_json(user, reasons=None, role=None, mandatory=False, rules=None, user_group=None): @@ -36,20 +37,20 @@ def reviewer_as_json(user, reasons=None, role=None, mandatory=False, rules=None, """ role = role or PullRequestReviewers.ROLE_REVIEWER if role not in PullRequestReviewers.ROLES: - raise ValueError('role is not one of %s', PullRequestReviewers.ROLES) + raise ValueError("role is not one of %s", PullRequestReviewers.ROLES) return { - 'user_id': user.user_id, - 'reasons': reasons or [], - 'rules': rules or [], - 'role': role, - 'mandatory': mandatory, - 'user_group': user_group, - 'username': user.username, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'user_link': h.link_to_user(user), - 'gravatar_link': h.gravatar_url(user.email, 14), + "user_id": user.user_id, + "reasons": reasons or [], + "rules": rules or [], + "role": role, + "mandatory": mandatory, + "user_group": user_group, + "username": user.username, + "first_name": user.first_name, + "last_name": user.last_name, + "user_link": h.link_to_user(user), + "gravatar_link": h.gravatar_url(user.email, 14), } @@ -60,34 +61,38 @@ def to_reviewers(e): return reviewer_as_json(e) -def get_default_reviewers_data(current_user, source_repo, source_ref, target_repo, target_ref, - include_diff_info=True): +def get_default_reviewers_data(current_user, source_repo, source_ref, target_repo, target_ref, include_diff_info=True): """ Return json for default reviewers of a repository """ diff_info = {} if include_diff_info: - diff_info = get_diff_info( - source_repo, source_ref.commit_id, target_repo, target_ref.commit_id) + diff_info = get_diff_info(source_repo, source_ref.commit_id, target_repo, target_ref.commit_id) - reasons = ['Default reviewer', 'Repository owner'] - json_reviewers = [reviewer_as_json( - user=target_repo.user, reasons=reasons, mandatory=False, rules=None, role=None)] + reasons = ["Default reviewer", "Repository owner"] + json_reviewers = [reviewer_as_json(user=target_repo.user, reasons=reasons, mandatory=False, rules=None, role=None)] compute_key = rc_cache.utils.compute_key_from_params( - current_user.user_id, source_repo.repo_id, source_ref.type, source_ref.name, - source_ref.commit_id, target_repo.repo_id, target_ref.type, target_ref.name, - target_ref.commit_id) + current_user.user_id, + source_repo.repo_id, + source_ref.type, + source_ref.name, + source_ref.commit_id, + target_repo.repo_id, + target_ref.type, + target_ref.name, + target_ref.commit_id, + ) return { - 'api_ver': REVIEWER_API_VERSION, # define version for later possible schema upgrade - 'compute_key': compute_key, - 'diff_info': diff_info, - 'reviewers': json_reviewers, - 'rules': {}, - 'rules_data': {}, - 'rules_humanized': [], + "api_ver": REVIEWER_API_VERSION, # define version for later possible schema upgrade + "compute_key": compute_key, + "diff_info": diff_info, + "reviewers": json_reviewers, + "rules": {}, + "rules_data": {}, + "rules_humanized": [], } @@ -98,8 +103,8 @@ def validate_default_reviewers(review_members, reviewer_rules): reviewers = [] reviewer_by_id = {} for r in review_members: - reviewer_user_id = safe_int(r['user_id']) - entry = (reviewer_user_id, r['reasons'], r['mandatory'], r['role'], r['rules']) + reviewer_user_id = safe_int(r["user_id"]) + entry = (reviewer_user_id, r["reasons"], r["mandatory"], r["role"], r["rules"]) reviewer_by_id[reviewer_user_id] = entry reviewers.append(entry) diff --git a/rhodecode/apps/repository/views/repo_artifacts.py b/rhodecode/apps/repository/views/repo_artifacts.py index 04535984..fed59ab6 100644 --- a/rhodecode/apps/repository/views/repo_artifacts.py +++ b/rhodecode/apps/repository/views/repo_artifacts.py @@ -19,25 +19,21 @@ import logging - from rhodecode.apps._base import RepoAppView -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator log = logging.getLogger(__name__) class RepoArtifactsView(RepoAppView): - def load_default_context(self): c = self._get_local_tmpl_context(include_app_defaults=True) c.rhodecode_repo = self.rhodecode_vcs_repo return c @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_artifacts(self): c = self.load_default_context() - c.active = 'artifacts' + c.active = "artifacts" return self._get_template_context(c) diff --git a/rhodecode/apps/repository/views/repo_audit_logs.py b/rhodecode/apps/repository/views/repo_audit_logs.py index 0e07dafa..b8358a87 100644 --- a/rhodecode/apps/repository/views/repo_audit_logs.py +++ b/rhodecode/apps/repository/views/repo_audit_logs.py @@ -35,28 +35,25 @@ class AuditLogsView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_audit_logs(self): _ = self.request.translate c = self.load_default_context() c.db_repo = self.db_repo - c.active = 'audit' + c.active = "audit" - p = safe_int(self.request.GET.get('page', 1), 1) + p = safe_int(self.request.GET.get("page", 1), 1) - filter_term = self.request.GET.get('filter') + filter_term = self.request.GET.get("filter") user_log = RepoModel().get_repo_log(c.db_repo, filter_term) def url_generator(page_num): - query_params = { - 'page': page_num - } + query_params = {"page": page_num} if filter_term: - query_params['filter'] = filter_term + query_params["filter"] = filter_term return self.request.current_route_path(_query=query_params) - c.audit_logs = SqlPage( - user_log, page=p, items_per_page=10, url_maker=url_generator) + c.audit_logs = SqlPage(user_log, page=p, items_per_page=10, url_maker=url_generator) c.filter_term = filter_term return self._get_template_context(c) diff --git a/rhodecode/apps/repository/views/repo_automation.py b/rhodecode/apps/repository/views/repo_automation.py index b39da22d..4a892bb9 100644 --- a/rhodecode/apps/repository/views/repo_automation.py +++ b/rhodecode/apps/repository/views/repo_automation.py @@ -19,7 +19,6 @@ import logging - from rhodecode.apps._base import RepoAppView from rhodecode.apps.repository.utils import get_default_reviewers_data from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator @@ -33,9 +32,9 @@ class RepoAutomationView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_automation(self): c = self.load_default_context() - c.active = 'automation' + c.active = "automation" return self._get_template_context(c) diff --git a/rhodecode/apps/repository/views/repo_bookmarks.py b/rhodecode/apps/repository/views/repo_bookmarks.py index ae8aec5f..4ce3cb1e 100644 --- a/rhodecode/apps/repository/views/repo_bookmarks.py +++ b/rhodecode/apps/repository/views/repo_bookmarks.py @@ -22,17 +22,15 @@ from pyramid.httpexceptions import HTTPNotFound from rhodecode.apps._base import BaseReferencesView from rhodecode.lib import ext_json from rhodecode.lib import helpers as h -from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.model.scm import ScmModel log = logging.getLogger(__name__) class RepoBookmarksView(BaseReferencesView): - @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def bookmarks(self): c = self.load_default_context() self._prepare_and_set_clone_url(c) @@ -43,8 +41,7 @@ class RepoBookmarksView(BaseReferencesView): raise HTTPNotFound() ref_items = self.rhodecode_vcs_repo.bookmarks.items() - data = self.load_refs_context( - ref_items=ref_items, partials_template='bookmarks/bookmarks_data.mako') + data = self.load_refs_context(ref_items=ref_items, partials_template="bookmarks/bookmarks_data.mako") c.has_references = bool(data) c.data = ext_json.str_json(data) diff --git a/rhodecode/apps/repository/views/repo_branch_permissions.py b/rhodecode/apps/repository/views/repo_branch_permissions.py index 6628bb64..ceae8cc1 100644 --- a/rhodecode/apps/repository/views/repo_branch_permissions.py +++ b/rhodecode/apps/repository/views/repo_branch_permissions.py @@ -19,7 +19,6 @@ import logging - from rhodecode.apps._base import RepoAppView from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator @@ -27,14 +26,13 @@ log = logging.getLogger(__name__) class RepoSettingsBranchPermissionsView(RepoAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def branch_permissions(self): c = self.load_default_context() - c.active = 'permissions_branch' + c.active = "permissions_branch" return self._get_template_context(c) diff --git a/rhodecode/apps/repository/views/repo_branches.py b/rhodecode/apps/repository/views/repo_branches.py index 0c6b6264..a4a5591f 100644 --- a/rhodecode/apps/repository/views/repo_branches.py +++ b/rhodecode/apps/repository/views/repo_branches.py @@ -23,7 +23,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import BaseReferencesView from rhodecode.lib import ext_json from rhodecode.lib import helpers as h -from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.model.scm import ScmModel from rhodecode.model.meta import Session from rhodecode.model.db import PullRequest @@ -32,26 +32,22 @@ log = logging.getLogger(__name__) class RepoBranchesView(BaseReferencesView): - @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def branches(self): - partial_render = self.request.get_partial_renderer( - 'rhodecode:templates/data_table/_dt_elements.mako') + partial_render = self.request.get_partial_renderer("rhodecode:templates/data_table/_dt_elements.mako") repo_name = self.db_repo_name c = self.load_default_context() self._prepare_and_set_clone_url(c) c.rhodecode_repo = self.rhodecode_vcs_repo c.repository_forks = ScmModel().get_forks(self.db_repo) ref_items = self.rhodecode_vcs_repo.branches_all.items() - data = self.load_refs_context( - ref_items=ref_items, partials_template='branches/branches_data.mako') + data = self.load_refs_context(ref_items=ref_items, partials_template="branches/branches_data.mako") data_with_actions = [] - if self.db_repo.repo_type != 'svn': + if self.db_repo.repo_type != "svn": for branch in data: - branch['action'] = partial_render( - f"branch_actions_{self.db_repo.repo_type}", branch['name_raw'], repo_name, closed=branch['closed'] + branch["action"] = partial_render( + f"branch_actions_{self.db_repo.repo_type}", branch["name_raw"], repo_name, closed=branch["closed"] ) data_with_actions.append(branch) data = data_with_actions @@ -60,7 +56,7 @@ class RepoBranchesView(BaseReferencesView): return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.write", "repository.admin") @CSRFRequired() def remove_branch(self): _ = self.request.translate @@ -68,40 +64,52 @@ class RepoBranchesView(BaseReferencesView): repo = self.db_repo repo_name = self.db_repo_name repo_type = repo.repo_type - action = _('deleted') if repo_type == 'git' else _('closed') - redirect = HTTPFound(location=self.request.route_path('branches_home', repo_name=repo_name)) - branch_name = self.request.matchdict.get('branch_name') + action = _("deleted") if repo_type == "git" else _("closed") + redirect = HTTPFound(location=self.request.route_path("branches_home", repo_name=repo_name)) + branch_name = self.request.matchdict.get("branch_name") if repo.landing_ref_name == branch_name: h.flash( _("This branch {} cannot be removed as it's currently set as landing branch").format(branch_name), - category='error' + category="error", ) return redirect - if prs_related_to := Session().query(PullRequest).filter(PullRequest.target_repo_id == repo.repo_id, - PullRequest.status != PullRequest.STATUS_CLOSED).filter( - (PullRequest.source_ref.like(f'branch:{branch_name}:%')) | ( - PullRequest.target_ref.like(f'branch:{branch_name}:%')) - ).all(): - h.flash(_("Branch cannot be {} - it's used in following open Pull Request ids: {}").format(action, ','.join( - map(str, prs_related_to))), category='error') + if ( + prs_related_to := Session() + .query(PullRequest) + .filter(PullRequest.target_repo_id == repo.repo_id, PullRequest.status != PullRequest.STATUS_CLOSED) + .filter( + (PullRequest.source_ref.like(f"branch:{branch_name}:%")) + | (PullRequest.target_ref.like(f"branch:{branch_name}:%")) + ) + .all() + ): + h.flash( + _("Branch cannot be {} - it's used in following open Pull Request ids: {}").format( + action, ",".join(map(str, prs_related_to)) + ), + category="error", + ) return redirect match repo_type: - case 'git': + case "git": self.rhodecode_vcs_repo.delete_branch(branch_name) - case 'hg': + case "hg": from rhodecode.lib.vcs.backends.base import Reference + self.rhodecode_vcs_repo._local_close( - source_ref=Reference(type='branch', name=branch_name, - commit_id=self.rhodecode_vcs_repo.branches[branch_name]), - target_ref=Reference(type='branch', name='', commit_id=None), + source_ref=Reference( + type="branch", name=branch_name, commit_id=self.rhodecode_vcs_repo.branches[branch_name] + ), + target_ref=Reference(type="branch", name="", commit_id=None), user_name=self.request.user.name, - user_email=self.request.user.email) + user_email=self.request.user.email, + ) case _: - raise NotImplementedError('Branch deleting functionality not yet implemented') + raise NotImplementedError("Branch deleting functionality not yet implemented") ScmModel().mark_for_invalidation(repo_name) - self.rhodecode_vcs_repo._invalidate_prop_cache('commit_ids') - self.rhodecode_vcs_repo._invalidate_prop_cache('_refs') - self.rhodecode_vcs_repo._invalidate_prop_cache('branches') - h.flash(_("Branch {} has been successfully {}").format(branch_name, action), category='success') + self.rhodecode_vcs_repo._invalidate_prop_cache("commit_ids") + self.rhodecode_vcs_repo._invalidate_prop_cache("_refs") + self.rhodecode_vcs_repo._invalidate_prop_cache("branches") + h.flash(_("Branch {} has been successfully {}").format(branch_name, action), category="success") return redirect diff --git a/rhodecode/apps/repository/views/repo_caches.py b/rhodecode/apps/repository/views/repo_caches.py index d78f4cb4..8db88e1d 100644 --- a/rhodecode/apps/repository/views/repo_caches.py +++ b/rhodecode/apps/repository/views/repo_caches.py @@ -23,8 +23,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import RepoAppView -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.lib import helpers as h, rc_cache from rhodecode.lib import system_info from rhodecode.model.meta import Session @@ -39,10 +38,10 @@ class RepoCachesView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_caches(self): c = self.load_default_context() - c.active = 'caches' + c.active = "caches" cached_diffs_dir = c.rhodecode_db_repo.cached_diffs_dir c.cached_diff_count = len(c.rhodecode_db_repo.cached_diffs()) c.cached_diff_size = 0 @@ -50,42 +49,38 @@ class RepoCachesView(RepoAppView): c.cached_diff_size = system_info.get_storage_size(cached_diffs_dir) c.shadow_repos = c.rhodecode_db_repo.shadow_repos() - cache_namespace_uid = f'repo.{self.db_repo.repo_id}' - c.region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) + cache_namespace_uid = f"repo.{self.db_repo.repo_id}" + c.region = rc_cache.get_or_create_region("cache_repo", cache_namespace_uid) c.backend = c.region.backend c.repo_keys = sorted(c.region.backend.list_keys(prefix=cache_namespace_uid)) return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_caches_purge(self): _ = self.request.translate c = self.load_default_context() - c.active = 'caches' + c.active = "caches" invalidated = 0 try: ScmModel().mark_for_invalidation(self.db_repo_name, delete=True) Session().commit() - invalidated +=1 + invalidated += 1 except Exception: log.exception("Exception during cache invalidation") - h.flash(_('An error occurred during cache invalidation'), - category='error') + h.flash(_("An error occurred during cache invalidation"), category="error") try: invalidated += 1 self.rhodecode_vcs_repo.vcsserver_invalidate_cache(delete=True) except Exception: log.exception("Exception during vcsserver cache invalidation") - h.flash(_('An error occurred during vcsserver cache invalidation'), - category='error') + h.flash(_("An error occurred during vcsserver cache invalidation"), category="error") if invalidated: - h.flash(_('Cache invalidation successful. Stages {}/2').format(invalidated), - category='success') + h.flash(_("Cache invalidation successful. Stages {}/2").format(invalidated), category="success") - raise HTTPFound(h.route_path( - 'edit_repo_caches', repo_name=self.db_repo_name)) \ No newline at end of file + raise HTTPFound(h.route_path("edit_repo_caches", repo_name=self.db_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_changelog.py b/rhodecode/apps/repository/views/repo_changelog.py index d5878a25..140b92ea 100644 --- a/rhodecode/apps/repository/views/repo_changelog.py +++ b/rhodecode/apps/repository/views/repo_changelog.py @@ -27,16 +27,19 @@ from pyramid.response import Response from rhodecode.apps._base import RepoAppView import rhodecode.lib.helpers as h from rhodecode.lib import ext_json -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.graphmod import _colored, _dagwalker from rhodecode.lib.helpers import RepoPage from rhodecode.lib.utils2 import str2bool from rhodecode.lib.str_utils import safe_int, safe_str, safe_bytes from rhodecode.lib.vcs.exceptions import ( - RepositoryError, CommitDoesNotExistError, - CommitError, NodeDoesNotExistError, EmptyRepositoryError) + RepositoryError, + CommitDoesNotExistError, + CommitError, + NodeDoesNotExistError, + EmptyRepositoryError, +) log = logging.getLogger(__name__) @@ -44,7 +47,6 @@ DEFAULT_CHANGELOG_SIZE = 20 class RepoChangelogView(RepoAppView): - def _get_commit_or_redirect(self, commit_id, redirect_after=True): """ This is a safe way to get commit. If an error occurs it redirects to @@ -61,17 +63,15 @@ class RepoChangelogView(RepoAppView): if not redirect_after: return None - h.flash(h.literal( - _('There are no commits yet')), category='warning') - raise HTTPFound( - h.route_path('repo_summary', repo_name=self.db_repo_name)) + h.flash(h.literal(_("There are no commits yet")), category="warning") + raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo_name)) except (CommitDoesNotExistError, LookupError): - msg = _('No such commit exists for this repository') - h.flash(msg, category='error') + msg = _("No such commit exists for this repository") + h.flash(msg, category="error") raise HTTPNotFound() except RepositoryError as e: - h.flash(h.escape(safe_str(e)), category='error') + h.flash(h.escape(safe_str(e)), category="error") raise HTTPNotFound() def _graph(self, repo, commits, prev_data=None, next_data=None): @@ -91,8 +91,7 @@ class RepoChangelogView(RepoAppView): branch=None, ) if parents: - data['parents'] = [ - serialize(x, parents=False) for x in commit.parents] + data["parents"] = [serialize(x, parents=False) for x in commit.parents] return data prev_data = prev_data or [] @@ -104,57 +103,51 @@ class RepoChangelogView(RepoAppView): dag = _dagwalker(repo, commits) - data = [[commit_id, vtx, edges, branch] - for commit_id, vtx, edges, branch in _colored(dag)] + data = [[commit_id, vtx, edges, branch] for commit_id, vtx, edges, branch in _colored(dag)] return ext_json.str_json(data), ext_json.str_json(current) def _check_if_valid_branch(self, branch_name, repo_name, f_path): if branch_name not in self.rhodecode_vcs_repo.branches_all: - h.flash(f'Branch {h.escape(safe_str(branch_name))} is not found.', - category='warning') + h.flash(f"Branch {h.escape(safe_str(branch_name))} is not found.", category="warning") redirect_url = h.route_path( - 'repo_commits_file', repo_name=repo_name, - commit_id=branch_name, f_path=f_path or '') + "repo_commits_file", repo_name=repo_name, commit_id=branch_name, f_path=f_path or "" + ) raise HTTPFound(redirect_url) def _load_changelog_data( - self, c, collection, page, chunk_size, branch_name=None, - dynamic=False, f_path=None, commit_id=None): - + self, c, collection, page, chunk_size, branch_name=None, dynamic=False, f_path=None, commit_id=None + ): def url_generator(page_num): - query_params = { - 'page': page_num - } + query_params = {"page": page_num} if branch_name: - query_params.update({ - 'branch': branch_name - }) + query_params.update({"branch": branch_name}) if f_path: # changelog for file return h.route_path( - 'repo_commits_file', + "repo_commits_file", repo_name=c.rhodecode_db_repo.repo_name, - commit_id=commit_id, f_path=f_path, - _query=query_params) + commit_id=commit_id, + f_path=f_path, + _query=query_params, + ) else: - return h.route_path( - 'repo_commits', - repo_name=c.rhodecode_db_repo.repo_name, _query=query_params) + return h.route_path("repo_commits", repo_name=c.rhodecode_db_repo.repo_name, _query=query_params) c.total_cs = len(collection) c.showing_commits = min(chunk_size, c.total_cs) - c.pagination = RepoPage(collection, page=page, item_count=c.total_cs, - items_per_page=chunk_size, url_maker=url_generator) + c.pagination = RepoPage( + collection, page=page, item_count=c.total_cs, items_per_page=chunk_size, url_maker=url_generator + ) c.next_page = c.pagination.next_page c.prev_page = c.pagination.previous_page if dynamic: - if self.request.GET.get('chunk') != 'next': + if self.request.GET.get("chunk") != "next": c.next_page = None - if self.request.GET.get('chunk') != 'prev': + if self.request.GET.get("chunk") != "prev": c.prev_page = None page_commit_ids = [x.raw_id for x in c.pagination] @@ -169,26 +162,25 @@ class RepoChangelogView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_changelog(self): c = self.load_default_context() - commit_id = self.request.matchdict.get('commit_id') + commit_id = self.request.matchdict.get("commit_id") f_path = self._get_f_path(self.request.matchdict) - show_hidden = str2bool(self.request.GET.get('evolve')) + show_hidden = str2bool(self.request.GET.get("evolve")) chunk_size = 20 - c.branch_name = branch_name = self.request.GET.get('branch') or '' - c.book_name = book_name = self.request.GET.get('bookmark') or '' + c.branch_name = branch_name = self.request.GET.get("branch") or "" + c.book_name = book_name = self.request.GET.get("bookmark") or "" c.f_path = f_path c.commit_id = commit_id c.show_hidden = show_hidden - hist_limit = safe_int(self.request.GET.get('limit')) or None + hist_limit = safe_int(self.request.GET.get("limit")) or None - p = safe_int(self.request.GET.get('page', 1), 1) + p = safe_int(self.request.GET.get("page", 1), 1) c.selected_name = branch_name or book_name if not commit_id and branch_name: @@ -197,11 +189,11 @@ class RepoChangelogView(RepoAppView): c.changelog_for_path = f_path pre_load = self.get_commit_preload_attrs() - partial_xhr = self.request.environ.get('HTTP_X_PARTIAL_XHR') + partial_xhr = self.request.environ.get("HTTP_X_PARTIAL_XHR") try: if f_path: - log.debug('generating changelog for path %s', f_path) + log.debug("generating changelog for path %s", f_path) # get the history for the file ! base_commit = self.rhodecode_vcs_repo.get_commit(commit_id) bytes_path = safe_bytes(f_path) @@ -217,48 +209,40 @@ class RepoChangelogView(RepoAppView): commit = self._get_commit_or_redirect(commit_id) collection = commit.get_path_history(bytes_path) except RepositoryError as e: - h.flash(safe_str(e), category='warning') - redirect_url = h.route_path( - 'repo_commits', repo_name=self.db_repo_name) + h.flash(safe_str(e), category="warning") + redirect_url = h.route_path("repo_commits", repo_name=self.db_repo_name) raise HTTPFound(redirect_url) collection = list(reversed(collection)) else: collection = self.rhodecode_vcs_repo.get_commits( - branch_name=branch_name, show_hidden=show_hidden, - pre_load=pre_load, translate_tags=False) + branch_name=branch_name, show_hidden=show_hidden, pre_load=pre_load, translate_tags=False + ) - self._load_changelog_data( - c, collection, p, chunk_size, c.branch_name, - f_path=f_path, commit_id=commit_id) + self._load_changelog_data(c, collection, p, chunk_size, c.branch_name, f_path=f_path, commit_id=commit_id) except EmptyRepositoryError as e: - h.flash(h.escape(safe_str(e)), category='warning') - raise HTTPFound( - h.route_path('repo_summary', repo_name=self.db_repo_name)) + h.flash(h.escape(safe_str(e)), category="warning") + raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo_name)) except HTTPFound: raise except (RepositoryError, CommitDoesNotExistError, Exception) as e: log.exception(safe_str(e)) - h.flash(h.escape(safe_str(e)), category='error') + h.flash(h.escape(safe_str(e)), category="error") if commit_id: # from single commit page, we redirect to main commits - raise HTTPFound( - h.route_path('repo_commits', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("repo_commits", repo_name=self.db_repo_name)) else: # otherwise we redirect to summary - raise HTTPFound( - h.route_path('repo_summary', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo_name)) - - - if partial_xhr or self.request.environ.get('HTTP_X_PJAX'): + if partial_xhr or self.request.environ.get("HTTP_X_PJAX"): # case when loading dynamic file history in file view # loading from ajax, we don't want the first result, it's popped # in the code above html = render( - 'rhodecode:templates/commits/changelog_file_history.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/commits/changelog_file_history.mako", self._get_template_context(c), self.request + ) return Response(html) commit_ids = [] @@ -266,39 +250,34 @@ class RepoChangelogView(RepoAppView): # only load graph data when not in file history mode commit_ids = c.pagination - c.graph_data, c.graph_commits = self._graph( - self.rhodecode_vcs_repo, commit_ids) + c.graph_data, c.graph_commits = self._graph(self.rhodecode_vcs_repo, commit_ids) return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commits_elements(self): c = self.load_default_context() - commit_id = self.request.matchdict.get('commit_id') + commit_id = self.request.matchdict.get("commit_id") f_path = self._get_f_path(self.request.matchdict) - show_hidden = str2bool(self.request.GET.get('evolve')) + show_hidden = str2bool(self.request.GET.get("evolve")) chunk_size = 20 - hist_limit = safe_int(self.request.GET.get('limit')) or None + hist_limit = safe_int(self.request.GET.get("limit")) or None def wrap_for_error(err): - html = '' \ - 'ERROR: {}' \ - ''.format(err) + html = 'ERROR: {}'.format(err) return Response(html) - c.branch_name = branch_name = self.request.GET.get('branch') or '' - c.book_name = book_name = self.request.GET.get('bookmark') or '' + c.branch_name = branch_name = self.request.GET.get("branch") or "" + c.book_name = book_name = self.request.GET.get("bookmark") or "" c.f_path = f_path c.commit_id = commit_id c.show_hidden = show_hidden c.selected_name = branch_name or book_name if branch_name and branch_name not in self.rhodecode_vcs_repo.branches_all: - return wrap_for_error( - safe_str(f'Branch: {branch_name} is not valid')) + return wrap_for_error(safe_str(f"Branch: {branch_name} is not valid")) pre_load = self.get_commit_preload_attrs() @@ -307,38 +286,35 @@ class RepoChangelogView(RepoAppView): base_commit = self.rhodecode_vcs_repo.get_commit(commit_id) except (RepositoryError, CommitDoesNotExistError, Exception) as e: log.exception(safe_str(e)) - raise HTTPFound( - h.route_path('repo_commits', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("repo_commits", repo_name=self.db_repo_name)) bytes_path = safe_bytes(f_path) collection = base_commit.get_path_history(bytes_path, limit=hist_limit, pre_load=pre_load) collection = list(reversed(collection)) else: collection = self.rhodecode_vcs_repo.get_commits( - branch_name=branch_name, show_hidden=show_hidden, pre_load=pre_load, - translate_tags=False) + branch_name=branch_name, show_hidden=show_hidden, pre_load=pre_load, translate_tags=False + ) - p = safe_int(self.request.GET.get('page', 1), 1) + p = safe_int(self.request.GET.get("page", 1), 1) try: - self._load_changelog_data( - c, collection, p, chunk_size, dynamic=True, - f_path=f_path, commit_id=commit_id) + self._load_changelog_data(c, collection, p, chunk_size, dynamic=True, f_path=f_path, commit_id=commit_id) except EmptyRepositoryError as e: return wrap_for_error(safe_str(e)) except (RepositoryError, CommitDoesNotExistError, Exception) as e: - log.exception('Failed to fetch commits') + log.exception("Failed to fetch commits") return wrap_for_error(safe_str(e)) prev_data = None next_data = None try: - prev_graph = ext_json.json.loads(self.request.POST.get('graph') or '{}') + prev_graph = ext_json.json.loads(self.request.POST.get("graph") or "{}") except ext_json.json.JSONDecodeError: prev_graph = {} - if self.request.GET.get('chunk') == 'prev': + if self.request.GET.get("chunk") == "prev": next_data = prev_graph - elif self.request.GET.get('chunk') == 'next': + elif self.request.GET.get("chunk") == "next": prev_data = prev_graph commit_ids = [] @@ -347,7 +323,7 @@ class RepoChangelogView(RepoAppView): commit_ids = c.pagination c.graph_data, c.graph_commits = self._graph( - self.rhodecode_vcs_repo, commit_ids, - prev_data=prev_data, next_data=next_data) + self.rhodecode_vcs_repo, commit_ids, prev_data=prev_data, next_data=next_data + ) return self._get_template_context(c) diff --git a/rhodecode/apps/repository/views/repo_checks.py b/rhodecode/apps/repository/views/repo_checks.py index b81f7dfe..8a551fbd 100644 --- a/rhodecode/apps/repository/views/repo_checks.py +++ b/rhodecode/apps/repository/views/repo_checks.py @@ -22,7 +22,7 @@ from pyramid.httpexceptions import HTTPFound, HTTPNotFound from rhodecode.apps._base import BaseAppView from rhodecode.lib import helpers as h -from rhodecode.lib.auth import (NotAnonymous, HasRepoPermissionAny) +from rhodecode.lib.auth import NotAnonymous, HasRepoPermissionAny from rhodecode.model.db import Repository from rhodecode.model.permission import PermissionModel from rhodecode.model.validation_schema.types import RepoNameType @@ -38,7 +38,7 @@ class RepoChecksView(BaseAppView): @NotAnonymous() def repo_creating(self): c = self.load_default_context() - repo_name = self.request.matchdict['repo_name'] + repo_name = self.request.matchdict["repo_name"] repo_name = RepoNameType().deserialize(None, repo_name) db_repo = Repository.get_by_repo_name(repo_name) @@ -48,16 +48,14 @@ class RepoChecksView(BaseAppView): # re-check permissions before redirecting to prevent resource # discovery by checking the 302 code - perm_set = ['repository.read', 'repository.write', 'repository.admin'] - has_perm = HasRepoPermissionAny(*perm_set)( - db_repo.repo_name, 'Repo Creating check') + perm_set = ["repository.read", "repository.write", "repository.admin"] + has_perm = HasRepoPermissionAny(*perm_set)(db_repo.repo_name, "Repo Creating check") if not has_perm: raise HTTPNotFound() - raise HTTPFound(h.route_path( - 'repo_summary', repo_name=db_repo.repo_name)) + raise HTTPFound(h.route_path("repo_summary", repo_name=db_repo.repo_name)) - c.task_id = self.request.GET.get('task_id') + c.task_id = self.request.GET.get("task_id") c.repo_name = repo_name return self._get_template_context(c) @@ -65,16 +63,17 @@ class RepoChecksView(BaseAppView): @NotAnonymous() def repo_creating_check(self): _ = self.request.translate - task_id = self.request.GET.get('task_id') + task_id = self.request.GET.get("task_id") self.load_default_context() - repo_name = self.request.matchdict['repo_name'] + repo_name = self.request.matchdict["repo_name"] - if task_id and task_id not in ['None']: + if task_id and task_id not in ["None"]: import rhodecode from rhodecode.lib.celerylib.loader import celery_app, exceptions + if rhodecode.CELERY_ENABLED: - log.debug('celery: checking result for task:%s', task_id) + log.debug("celery: checking result for task:%s", task_id) task = celery_app.AsyncResult(task_id) try: task.get(timeout=10) @@ -82,34 +81,29 @@ class RepoChecksView(BaseAppView): task = None if task and task.failed(): msg = self._log_creation_exception(task.result, repo_name) - h.flash(msg, category='error') - raise HTTPFound(h.route_path('home'), code=501) + h.flash(msg, category="error") + raise HTTPFound(h.route_path("home"), code=501) db_repo = Repository.get_by_repo_name(repo_name) if db_repo and db_repo.repo_state == Repository.STATE_CREATED: if db_repo.clone_uri: clone_uri = db_repo.clone_uri_hidden - h.flash(_('Created repository %s from %s') - % (db_repo.repo_name, clone_uri), category='success') + h.flash(_("Created repository %s from %s") % (db_repo.repo_name, clone_uri), category="success") else: - repo_url = h.link_to( - db_repo.repo_name, - h.route_path('repo_summary', repo_name=db_repo.repo_name)) + repo_url = h.link_to(db_repo.repo_name, h.route_path("repo_summary", repo_name=db_repo.repo_name)) fork = db_repo.fork if fork: fork_name = fork.repo_name - h.flash(h.literal(_('Forked repository %s as %s') - % (fork_name, repo_url)), category='success') + h.flash(h.literal(_("Forked repository %s as %s") % (fork_name, repo_url)), category="success") else: - h.flash(h.literal(_('Created repository %s') % repo_url), - category='success') + h.flash(h.literal(_("Created repository %s") % repo_url), category="success") self.flush_permissions_on_creation(db_repo) - return {'result': True} - return {'result': False} + return {"result": True} + return {"result": False} def flush_permissions_on_creation(self, db_repo): # repo is finished and created, we flush the permissions now user_group_perms = db_repo.permissions(expand_from_user_groups=True) - affected_user_ids = [perm['user_id'] for perm in user_group_perms] + affected_user_ids = [perm["user_id"] for perm in user_group_perms] PermissionModel().trigger_permission_flush(affected_user_ids) diff --git a/rhodecode/apps/repository/views/repo_commits.py b/rhodecode/apps/repository/views/repo_commits.py index 76acd50f..23cefd7f 100644 --- a/rhodecode/apps/repository/views/repo_commits.py +++ b/rhodecode/apps/repository/views/repo_commits.py @@ -19,8 +19,7 @@ import logging import collections -from pyramid.httpexceptions import ( - HTTPNotFound, HTTPBadRequest, HTTPFound, HTTPForbidden, HTTPConflict) +from pyramid.httpexceptions import HTTPNotFound, HTTPBadRequest, HTTPFound, HTTPForbidden, HTTPConflict from pyramid.renderers import render from pyramid.response import Response @@ -29,21 +28,22 @@ from rhodecode.apps.file_store import utils as store_utils from rhodecode.apps.file_store.exceptions import FileNotAllowedException, FileOverSizeException from rhodecode.lib import diffs, codeblocks, channelstream -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired from rhodecode.lib import ext_json from collections import OrderedDict from rhodecode.lib.diffs import ( - cache_diff, load_cached_diff, diff_cache_exist, get_diff_context, - get_diff_whitespace_flag) + cache_diff, + load_cached_diff, + diff_cache_exist, + get_diff_context, + get_diff_whitespace_flag, +) from rhodecode.lib.exceptions import StatusChangeOnClosedPullRequestError, CommentVersionMismatch import rhodecode.lib.helpers as h from rhodecode.lib.utils2 import str2bool, StrictAttributeDict, safe_str from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.vcs.exceptions import ( - RepositoryError, CommitDoesNotExistError) -from rhodecode.model.db import ChangesetComment, ChangesetStatus, FileStore, \ - ChangesetCommentHistory +from rhodecode.lib.vcs.exceptions import RepositoryError, CommitDoesNotExistError +from rhodecode.model.db import ChangesetComment, ChangesetStatus, FileStore, ChangesetCommentHistory from rhodecode.model.changeset_status import ChangesetStatusModel from rhodecode.model.comment import CommentsModel from rhodecode.model.meta import Session @@ -53,7 +53,7 @@ log = logging.getLogger(__name__) def _update_with_GET(params, request): - for k in ['diff1', 'diff2', 'diff']: + for k in ["diff1", "diff2", "diff"]: params[k] += request.GET.getall(k) @@ -65,16 +65,15 @@ class RepoCommitsView(RepoAppView): return c def _is_diff_cache_enabled(self, target_repo): - caching_enabled = self._get_general_setting( - target_repo, 'rhodecode_diff_cache') - log.debug('Diff caching enabled: %s', caching_enabled) + caching_enabled = self._get_general_setting(target_repo, "rhodecode_diff_cache") + log.debug("Diff caching enabled: %s", caching_enabled) return caching_enabled def _commit(self, commit_id_range, method): _ = self.request.translate c = self.load_default_context() - c.fulldiff = self.request.GET.get('fulldiff') - redirect_to_combined = str2bool(self.request.GET.get('redirect_combined')) + c.fulldiff = self.request.GET.get("fulldiff") + redirect_to_combined = str2bool(self.request.GET.get("redirect_combined")) # fetch global flags of ignore ws or context lines diff_context = get_diff_context(self.request) @@ -86,27 +85,27 @@ class RepoCommitsView(RepoAppView): file_limit = c.visual.cut_off_limit_file # get ranges of commit ids if preset - commit_range = commit_id_range.split('...')[:2] + commit_range = commit_id_range.split("...")[:2] try: - pre_load = ['author', 'branch', 'date', 'message', 'parents'] - if self.rhodecode_vcs_repo.alias == 'hg': - pre_load += ['hidden', 'obsolete', 'phase'] + pre_load = ["author", "branch", "date", "message", "parents"] + if self.rhodecode_vcs_repo.alias == "hg": + pre_load += ["hidden", "obsolete", "phase"] if len(commit_range) == 2: commits = self.rhodecode_vcs_repo.get_commits( - start_id=commit_range[0], end_id=commit_range[1], - pre_load=pre_load, translate_tags=False) + start_id=commit_range[0], end_id=commit_range[1], pre_load=pre_load, translate_tags=False + ) commits = list(commits) else: commits = [self.rhodecode_vcs_repo.get_commit(commit_id=commit_id_range, pre_load=pre_load)] c.commit_ranges = commits if not c.commit_ranges: - raise RepositoryError('The commit range returned an empty result') + raise RepositoryError("The commit range returned an empty result") except CommitDoesNotExistError as e: - msg = _('No such commit exists. Org exception: `{}`').format(safe_str(e)) - h.flash(msg, category='error') + msg = _("No such commit exists. Org exception: `{}`").format(safe_str(e)) + h.flash(msg, category="error") raise HTTPNotFound() except Exception: log.exception("General failure") @@ -114,16 +113,18 @@ class RepoCommitsView(RepoAppView): single_commit = len(c.commit_ranges) == 1 if redirect_to_combined and not single_commit: - source_ref = getattr(c.commit_ranges[0].parents[0] - if c.commit_ranges[0].parents else h.EmptyCommit(), 'raw_id') + source_ref = getattr( + c.commit_ranges[0].parents[0] if c.commit_ranges[0].parents else h.EmptyCommit(), "raw_id" + ) target_ref = c.commit_ranges[-1].raw_id next_url = h.route_path( - 'repo_compare', + "repo_compare", repo_name=c.repo_name, - source_ref_type='rev', + source_ref_type="rev", source_ref=source_ref, - target_ref_type='rev', - target_ref=target_ref) + target_ref_type="rev", + target_ref=target_ref, + ) raise HTTPFound(next_url) c.changes = OrderedDict() @@ -145,20 +146,15 @@ class RepoCommitsView(RepoAppView): # Single commit if single_commit: commit = c.commit_ranges[0] - c.comments = CommentsModel().get_comments( - self.db_repo.repo_id, - revision=commit.raw_id) + c.comments = CommentsModel().get_comments(self.db_repo.repo_id, revision=commit.raw_id) # comments from PR - statuses = ChangesetStatusModel().get_statuses( - self.db_repo.repo_id, commit.raw_id, - with_revisions=True) + statuses = ChangesetStatusModel().get_statuses(self.db_repo.repo_id, commit.raw_id, with_revisions=True) prs = set() reviewers = list() reviewers_duplicates = set() # to not have duplicates from multiple votes for c_status in statuses: - # extract associated pull-requests from votes if c_status.pull_request: prs.add(c_status.pull_request) @@ -167,15 +163,16 @@ class RepoCommitsView(RepoAppView): _user_id = c_status.author.user_id if _user_id not in reviewers_duplicates: reviewers.append( - StrictAttributeDict({ - 'user': c_status.author, - - # fake attributed for commit, page that we don't have - # but we share the display with PR page - 'mandatory': False, - 'reasons': [], - 'rule_user_group_data': lambda: None - }) + StrictAttributeDict( + { + "user": c_status.author, + # fake attributed for commit, page that we don't have + # but we share the display with PR page + "mandatory": False, + "reasons": [], + "rule_user_group_data": lambda: None, + } + ) ) reviewers_duplicates.add(_user_id) @@ -187,32 +184,27 @@ class RepoCommitsView(RepoAppView): for pr in prs: c.comments.extend(pr.comments) - c.unresolved_comments = CommentsModel()\ - .get_commit_unresolved_todos(commit.raw_id) - c.resolved_comments = CommentsModel()\ - .get_commit_resolved_todos(commit.raw_id) + c.unresolved_comments = CommentsModel().get_commit_unresolved_todos(commit.raw_id) + c.resolved_comments = CommentsModel().get_commit_resolved_todos(commit.raw_id) - c.inline_comments_flat = CommentsModel()\ - .get_commit_inline_comments(commit.raw_id) + c.inline_comments_flat = CommentsModel().get_commit_inline_comments(commit.raw_id) - review_statuses = ChangesetStatusModel().aggregate_votes_by_user( - statuses, reviewers) + review_statuses = ChangesetStatusModel().aggregate_votes_by_user(statuses, reviewers) c.commit_review_status = ChangesetStatus.STATUS_NOT_REVIEWED - c.commit_set_reviewers_data_json = collections.OrderedDict({'reviewers': []}) + c.commit_set_reviewers_data_json = collections.OrderedDict({"reviewers": []}) for review_obj, member, reasons, mandatory, status in review_statuses: member_reviewer = h.reviewer_as_json( - member, reasons=reasons, mandatory=mandatory, role=None, - user_group=None + member, reasons=reasons, mandatory=mandatory, role=None, user_group=None ) current_review_status = status[0][1].status if status else ChangesetStatus.STATUS_NOT_REVIEWED - member_reviewer['review_status'] = current_review_status - member_reviewer['review_status_label'] = h.commit_status_lbl(current_review_status) - member_reviewer['allowed_to_update'] = False - c.commit_set_reviewers_data_json['reviewers'].append(member_reviewer) + member_reviewer["review_status"] = current_review_status + member_reviewer["review_status_label"] = h.commit_status_lbl(current_review_status) + member_reviewer["allowed_to_update"] = False + c.commit_set_reviewers_data_json["reviewers"].append(member_reviewer) c.commit_set_reviewers_data_json = ext_json.str_json(c.commit_set_reviewers_data_json) @@ -228,49 +220,50 @@ class RepoCommitsView(RepoAppView): commit2 = commit commit1 = commit.first_parent - if method == 'show': - inline_comments = CommentsModel().get_inline_comments( - self.db_repo.repo_id, revision=commit.raw_id) - c.inline_cnt = len(CommentsModel().get_inline_comments_as_list( - inline_comments)) + if method == "show": + inline_comments = CommentsModel().get_inline_comments(self.db_repo.repo_id, revision=commit.raw_id) + c.inline_cnt = len(CommentsModel().get_inline_comments_as_list(inline_comments)) c.inline_comments = inline_comments - cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path( - self.db_repo) + cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path(self.db_repo) cache_file_path = diff_cache_exist( - cache_path, 'diff', commit.raw_id, - hide_whitespace_changes, diff_context, c.fulldiff) + cache_path, "diff", commit.raw_id, hide_whitespace_changes, diff_context, c.fulldiff + ) caching_enabled = self._is_diff_cache_enabled(self.db_repo) - force_recache = str2bool(self.request.GET.get('force_recache')) + force_recache = str2bool(self.request.GET.get("force_recache")) cached_diff = None if caching_enabled: cached_diff = load_cached_diff(cache_file_path) - has_proper_diff_cache = cached_diff and cached_diff.get('diff') + has_proper_diff_cache = cached_diff and cached_diff.get("diff") if not force_recache and has_proper_diff_cache: - diffset = cached_diff['diff'] + diffset = cached_diff["diff"] else: vcs_diff = self.rhodecode_vcs_repo.get_diff( - commit1, commit2, - ignore_whitespace=hide_whitespace_changes, - context=diff_context) + commit1, commit2, ignore_whitespace=hide_whitespace_changes, context=diff_context + ) - diff_processor = diffs.DiffProcessor(vcs_diff, diff_format='newdiff', - diff_limit=diff_limit, - file_limit=file_limit, - show_full_diff=c.fulldiff) + diff_processor = diffs.DiffProcessor( + vcs_diff, + diff_format="newdiff", + diff_limit=diff_limit, + file_limit=file_limit, + show_full_diff=c.fulldiff, + ) _parsed = diff_processor.prepare() diffset = codeblocks.DiffSet( repo_name=self.db_repo_name, source_node_getter=codeblocks.diffset_node_getter(commit1), - target_node_getter=codeblocks.diffset_node_getter(commit2)) + target_node_getter=codeblocks.diffset_node_getter(commit2), + ) diffset = self.path_filter.render_patchset_filtered( - diffset, _parsed, commit1.raw_id, commit2.raw_id) + diffset, _parsed, commit1.raw_id, commit2.raw_id + ) # save cached diff if caching_enabled: @@ -281,11 +274,15 @@ class RepoCommitsView(RepoAppView): else: # TODO(marcink): no cache usage here... _diff = self.rhodecode_vcs_repo.get_diff( - commit1, commit2, - ignore_whitespace=hide_whitespace_changes, context=diff_context) - diff_processor = diffs.DiffProcessor(_diff, diff_format='newdiff', - diff_limit=diff_limit, - file_limit=file_limit, show_full_diff=c.fulldiff) + commit1, commit2, ignore_whitespace=hide_whitespace_changes, context=diff_context + ) + diff_processor = diffs.DiffProcessor( + _diff, + diff_format="newdiff", + diff_limit=diff_limit, + file_limit=file_limit, + show_full_diff=c.fulldiff, + ) # downloads/raw we only need RAW diff nothing else diff = self.path_filter.get_raw_patch(diff_processor) c.changes[commit.raw_id] = [None, None, None, None, diff, None, None] @@ -296,71 +293,64 @@ class RepoCommitsView(RepoAppView): if len(c.commit_ranges) == 1: c.commit = c.commit_ranges[0] - c.parent_tmpl = ''.join( - '# Parent %s\n' % x.raw_id for x in c.commit.parents) + c.parent_tmpl = "".join("# Parent %s\n" % x.raw_id for x in c.commit.parents) - if method == 'download': + if method == "download": response = Response(diff) - response.content_type = 'text/plain' - response.content_disposition = ( - 'attachment; filename=%s.diff' % commit_id_range[:12]) + response.content_type = "text/plain" + response.content_disposition = "attachment; filename=%s.diff" % commit_id_range[:12] return response - elif method == 'patch': - + elif method == "patch": c.diff = safe_str(diff) patch = render( - 'rhodecode:templates/changeset/patch_changeset.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/changeset/patch_changeset.mako", self._get_template_context(c), self.request + ) response = Response(patch) - response.content_type = 'text/plain' + response.content_type = "text/plain" return response - elif method == 'raw': + elif method == "raw": response = Response(diff) - response.content_type = 'text/plain' + response.content_type = "text/plain" return response - elif method == 'show': + elif method == "show": if len(c.commit_ranges) == 1: html = render( - 'rhodecode:templates/changeset/changeset.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/changeset/changeset.mako", self._get_template_context(c), self.request + ) return Response(html) else: c.ancestor = None c.target_repo = self.db_repo html = render( - 'rhodecode:templates/changeset/changeset_range.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/changeset/changeset_range.mako", self._get_template_context(c), self.request + ) return Response(html) raise HTTPBadRequest() @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commit_show(self): - commit_id = self.request.matchdict['commit_id'] - return self._commit(commit_id, method='show') + commit_id = self.request.matchdict["commit_id"] + return self._commit(commit_id, method="show") @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commit_raw(self): - commit_id = self.request.matchdict['commit_id'] - return self._commit(commit_id, method='raw') + commit_id = self.request.matchdict["commit_id"] + return self._commit(commit_id, method="raw") @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commit_patch(self): - commit_id = self.request.matchdict['commit_id'] - return self._commit(commit_id, method='patch') + commit_id = self.request.matchdict["commit_id"] + return self._commit(commit_id, method="patch") @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commit_download(self): - commit_id = self.request.matchdict['commit_id'] - return self._commit(commit_id, method='download') + commit_id = self.request.matchdict["commit_id"] + return self._commit(commit_id, method="download") def _commit_comments_create(self, commit_id, comments): _ = self.request.translate @@ -370,22 +360,23 @@ class RepoCommitsView(RepoAppView): commit = self.db_repo.get_commit(commit_id) - all_drafts = len([x for x in comments if str2bool(x['is_draft'])]) == len(comments) + all_drafts = len([x for x in comments if str2bool(x["is_draft"])]) == len(comments) for entry in comments: c = self.load_default_context() - comment_type = entry['comment_type'] - text = entry['text'] - status = entry['status'] - is_draft = str2bool(entry['is_draft']) - resolves_comment_id = entry['resolves_comment_id'] - f_path = entry['f_path'] - line_no = entry['line'] - target_elem_id = f'file-{h.safeid(h.safe_str(f_path))}' + comment_type = entry["comment_type"] + text = entry["text"] + status = entry["status"] + is_draft = str2bool(entry["is_draft"]) + resolves_comment_id = entry["resolves_comment_id"] + f_path = entry["f_path"] + line_no = entry["line"] + target_elem_id = f"file-{h.safeid(h.safe_str(f_path))}" if status: - text = text or (_('Status change %(transition_icon)s %(status)s') - % {'transition_icon': '>', - 'status': ChangesetStatus.get_status_lbl(status)}) + text = text or ( + _("Status change %(transition_icon)s %(status)s") + % {"transition_icon": ">", "status": ChangesetStatus.get_status_lbl(status)} + ) comment = CommentsModel().create( text=text, @@ -394,8 +385,7 @@ class RepoCommitsView(RepoAppView): commit_id=commit_id, f_path=f_path, line_no=line_no, - status_change=(ChangesetStatus.get_status_lbl(status) - if status else None), + status_change=(ChangesetStatus.get_status_lbl(status) if status else None), status_change_type=status, comment_type=comment_type, is_draft=is_draft, @@ -418,16 +408,13 @@ class RepoCommitsView(RepoAppView): self._rhodecode_db_user.user_id, comment, revision=commit_id, - dont_allow_on_closed_pull_request=True + dont_allow_on_closed_pull_request=True, ) except StatusChangeOnClosedPullRequestError: - msg = _('Changing the status of a commit associated with ' - 'a closed pull request is not allowed') + msg = _("Changing the status of a commit associated with a closed pull request is not allowed") log.exception(msg) - h.flash(msg, category='warning') - raise HTTPFound(h.route_path( - 'repo_commit', repo_name=self.db_repo_name, - commit_id=commit_id)) + h.flash(msg, category="warning") + raise HTTPFound(h.route_path("repo_commit", repo_name=self.db_repo_name, commit_id=commit_id)) Session().flush() # this is somehow required to get access to some relationship @@ -437,58 +424,56 @@ class RepoCommitsView(RepoAppView): # skip notifications for drafts if not is_draft: CommentsModel().trigger_commit_comment_hook( - self.db_repo, self._rhodecode_user, 'create', - data={'comment': comment, 'commit': commit}) + self.db_repo, self._rhodecode_user, "create", data={"comment": comment, "commit": commit} + ) comment_id = comment.comment_id - data[comment_id] = { - 'target_id': target_elem_id - } + data[comment_id] = {"target_id": target_elem_id} Session().flush() c.co = comment c.at_version_num = 0 c.is_new = True rendered_comment = render( - 'rhodecode:templates/changeset/changeset_comment_block.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/changeset/changeset_comment_block.mako", + self._get_template_context(c), + self.request, + ) data[comment_id].update(comment.get_dict()) - data[comment_id].update({'rendered_text': rendered_comment}) + data[comment_id].update({"rendered_text": rendered_comment}) # finalize, commit and redirect Session().commit() # skip channelstream for draft comments if not all_drafts: - comment_broadcast_channel = channelstream.comment_channel( - self.db_repo_name, commit_obj=commit) + comment_broadcast_channel = channelstream.comment_channel(self.db_repo_name, commit_obj=commit) comment_data = data - posted_comment_type = 'inline' if is_inline else 'general' + posted_comment_type = "inline" if is_inline else "general" if len(data) == 1: - msg = _('posted {} new {} comment').format(len(data), posted_comment_type) + msg = _("posted {} new {} comment").format(len(data), posted_comment_type) else: - msg = _('posted {} new {} comments').format(len(data), posted_comment_type) + msg = _("posted {} new {} comments").format(len(data), posted_comment_type) channelstream.comment_channelstream_push( - self.request, comment_broadcast_channel, self._rhodecode_user, msg, - comment_data=comment_data) + self.request, comment_broadcast_channel, self._rhodecode_user, msg, comment_data=comment_data + ) return data @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def repo_commit_comment_create(self): _ = self.request.translate - commit_id = self.request.matchdict['commit_id'] + commit_id = self.request.matchdict["commit_id"] multi_commit_ids = [] - for _commit_id in self.request.POST.get('commit_ids', '').split(','): - if _commit_id not in ['', None, EmptyCommit.raw_id]: + for _commit_id in self.request.POST.get("commit_ids", "").split(","): + if _commit_id not in ["", None, EmptyCommit.raw_id]: if _commit_id not in multi_commit_ids: multi_commit_ids.append(_commit_id) @@ -498,14 +483,14 @@ class RepoCommitsView(RepoAppView): # Multiple comments for each passed commit id for current_id in filter(None, commit_ids): comment_data = { - 'comment_type': self.request.POST.get('comment_type'), - 'text': self.request.POST.get('text'), - 'status': self.request.POST.get('changeset_status', None), - 'is_draft': self.request.POST.get('draft'), - 'resolves_comment_id': self.request.POST.get('resolves_comment_id', None), - 'close_pull_request': self.request.POST.get('close_pull_request'), - 'f_path': self.request.POST.get('f_path'), - 'line': self.request.POST.get('line'), + "comment_type": self.request.POST.get("comment_type"), + "text": self.request.POST.get("text"), + "status": self.request.POST.get("changeset_status", None), + "is_draft": self.request.POST.get("draft"), + "resolves_comment_id": self.request.POST.get("resolves_comment_id", None), + "close_pull_request": self.request.POST.get("close_pull_request"), + "f_path": self.request.POST.get("f_path"), + "line": self.request.POST.get("line"), } comment = self._commit_comments_create(commit_id=current_id, comments=[comment_data]) data.append(comment) @@ -514,8 +499,7 @@ class RepoCommitsView(RepoAppView): @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def repo_commit_comment_preview(self): # Technically a CSRF token is not needed as no state changes with this @@ -524,24 +508,22 @@ class RepoCommitsView(RepoAppView): # Post is required because the payload could be bigger than the maximum # allowed by GET. - text = self.request.POST.get('text') - renderer = self.request.POST.get('renderer') or 'rst' + text = self.request.POST.get("text") + renderer = self.request.POST.get("renderer") or "rst" if text: - return h.render(text, renderer=renderer, mentions=True, - repo_name=self.db_repo_name) - return '' + return h.render(text, renderer=renderer, mentions=True, repo_name=self.db_repo_name) + return "" @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def repo_commit_comment_history_view(self): c = self.load_default_context() - comment_id = self.request.matchdict['comment_id'] - comment_history_id = self.request.matchdict['comment_history_id'] + comment_id = self.request.matchdict["comment_id"] + comment_history_id = self.request.matchdict["comment_history_id"] comment = ChangesetComment.get_or_404(comment_id) - comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id) + comment_owner = comment.author.user_id == self._rhodecode_db_user.user_id if comment.draft and not comment_owner: # if we see draft comments history, we only allow this for owner raise HTTPNotFound() @@ -553,129 +535,135 @@ class RepoCommitsView(RepoAppView): c.comment_history = comment_history rendered_comment = render( - 'rhodecode:templates/changeset/comment_history.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/changeset/comment_history.mako", self._get_template_context(c), self.request + ) return rendered_comment else: - log.warning('No permissions for user %s to show comment_history_id: %s', - self._rhodecode_db_user, comment_history_id) + log.warning( + "No permissions for user %s to show comment_history_id: %s", self._rhodecode_db_user, comment_history_id + ) raise HTTPNotFound() @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def repo_commit_comment_attachment_upload(self): c = self.load_default_context() - upload_key = 'attachment' + upload_key = "attachment" file_obj = self.request.POST.get(upload_key) if file_obj is None: self.request.response.status = 400 - return {'store_fid': None, - 'access_path': None, - 'error': f'{upload_key} data field is missing'} + return {"store_fid": None, "access_path": None, "error": f"{upload_key} data field is missing"} - if not hasattr(file_obj, 'filename'): + if not hasattr(file_obj, "filename"): self.request.response.status = 400 - return {'store_fid': None, - 'access_path': None, - 'error': 'filename cannot be read from the data field'} + return {"store_fid": None, "access_path": None, "error": "filename cannot be read from the data field"} filename = file_obj.filename file_display_name = filename metadata = { - 'user_uploaded': {'username': self._rhodecode_user.username, - 'user_id': self._rhodecode_user.user_id, - 'ip': self._rhodecode_user.ip_addr}} + "user_uploaded": { + "username": self._rhodecode_user.username, + "user_id": self._rhodecode_user.user_id, + "ip": self._rhodecode_user.ip_addr, + } + } # TODO(marcink): allow .ini configuration for allowed_extensions, and file-size allowed_extensions = [ - 'gif', '.jpeg', '.jpg', '.png', '.docx', '.gz', '.log', '.pdf', - '.pptx', '.txt', '.xlsx', '.zip'] + "gif", + ".jpeg", + ".jpg", + ".png", + ".docx", + ".gz", + ".log", + ".pdf", + ".pptx", + ".txt", + ".xlsx", + ".zip", + ] max_file_size = 10 * 1024 * 1024 # 10MB, also validated via dropzone.js try: f_store = store_utils.get_filestore_backend(self.request.registry.settings) store_uid, metadata = f_store.store( - filename, file_obj.file, metadata=metadata, - extensions=allowed_extensions, max_filesize=max_file_size) + filename, file_obj.file, metadata=metadata, extensions=allowed_extensions, max_filesize=max_file_size + ) except FileNotAllowedException: self.request.response.status = 400 - permitted_extensions = ', '.join(allowed_extensions) - error_msg = f'File `{filename}` is not allowed. ' \ - f'Only following extensions are permitted: {permitted_extensions}' + permitted_extensions = ", ".join(allowed_extensions) + error_msg = ( + f"File `{filename}` is not allowed. Only following extensions are permitted: {permitted_extensions}" + ) - return {'store_fid': None, - 'access_path': None, - 'error': error_msg} + return {"store_fid": None, "access_path": None, "error": error_msg} except FileOverSizeException: self.request.response.status = 400 limit_mb = h.format_byte_size_binary(max_file_size) - error_msg = f'File {filename} is exceeding allowed limit of {limit_mb}.' - return {'store_fid': None, - 'access_path': None, - 'error': error_msg} + error_msg = f"File {filename} is exceeding allowed limit of {limit_mb}." + return {"store_fid": None, "access_path": None, "error": error_msg} try: entry = FileStore.create( - file_uid=store_uid, filename=metadata["filename"], - file_hash=metadata["sha256"], file_size=metadata["size"], + file_uid=store_uid, + filename=metadata["filename"], + file_hash=metadata["sha256"], + file_size=metadata["size"], file_display_name=file_display_name, - file_description=f'comment attachment `{safe_str(filename)}`', - hidden=True, check_acl=True, user_id=self._rhodecode_user.user_id, - scope_repo_id=self.db_repo.repo_id + file_description=f"comment attachment `{safe_str(filename)}`", + hidden=True, + check_acl=True, + user_id=self._rhodecode_user.user_id, + scope_repo_id=self.db_repo.repo_id, ) Session().add(entry) Session().commit() - log.debug('Stored upload in DB as %s', entry) + log.debug("Stored upload in DB as %s", entry) except Exception: - log.exception('Failed to store file %s', filename) + log.exception("Failed to store file %s", filename) self.request.response.status = 400 - return {'store_fid': None, - 'access_path': None, - 'error': f'File {filename} failed to store in DB.'} + return {"store_fid": None, "access_path": None, "error": f"File {filename} failed to store in DB."} Session().commit() data = { - 'store_fid': store_uid, - 'access_path': h.route_path( - 'download_file', fid=store_uid), - 'fqn_access_path': h.route_url( - 'download_file', fid=store_uid), + "store_fid": store_uid, + "access_path": h.route_path("download_file", fid=store_uid), + "fqn_access_path": h.route_url("download_file", fid=store_uid), # for EE those are replaced by FQN links on repo-only like - 'repo_access_path': h.route_url( - 'download_file', fid=store_uid), - 'repo_fqn_access_path': h.route_url( - 'download_file', fid=store_uid), + "repo_access_path": h.route_url("download_file", fid=store_uid), + "repo_fqn_access_path": h.route_url("download_file", fid=store_uid), } # this data is a part of CE/EE additional code - if c.rhodecode_edition_id == 'EE': - data.update({ - 'repo_access_path': h.route_path( - 'repo_artifacts_get', repo_name=self.db_repo_name, uid=store_uid), - 'repo_fqn_access_path': h.route_url( - 'repo_artifacts_get', repo_name=self.db_repo_name, uid=store_uid), - }) + if c.rhodecode_edition_id == "EE": + data.update( + { + "repo_access_path": h.route_path("repo_artifacts_get", repo_name=self.db_repo_name, uid=store_uid), + "repo_fqn_access_path": h.route_url( + "repo_artifacts_get", repo_name=self.db_repo_name, uid=store_uid + ), + } + ) return data @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def repo_commit_comment_delete(self): - commit_id = self.request.matchdict['commit_id'] - comment_id = self.request.matchdict['comment_id'] + commit_id = self.request.matchdict["commit_id"] + comment_id = self.request.matchdict["comment_id"] comment = ChangesetComment.get_or_404(comment_id) if not comment: - log.debug('Comment with id:%s not found, skipping', comment_id) + log.debug("Comment with id:%s not found, skipping", comment_id) # comment already deleted in another call probably return True @@ -683,9 +671,9 @@ class RepoCommitsView(RepoAppView): # don't allow deleting comments that are immutable raise HTTPForbidden() - is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name) - super_admin = h.HasPermissionAny('hg.admin')() - comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id) + is_repo_admin = h.HasRepoPermissionAny("repository.admin")(self.db_repo_name) + super_admin = h.HasPermissionAny("hg.admin")() + comment_owner = comment.author.user_id == self._rhodecode_db_user.user_id is_repo_comment = comment.repo.repo_id == self.db_repo.repo_id comment_repo_admin = is_repo_admin and is_repo_comment @@ -698,40 +686,36 @@ class RepoCommitsView(RepoAppView): Session().commit() return True else: - log.warning('No permissions for user %s to delete comment_id: %s', - self._rhodecode_db_user, comment_id) + log.warning("No permissions for user %s to delete comment_id: %s", self._rhodecode_db_user, comment_id) raise HTTPNotFound() @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def repo_commit_comment_edit(self): self.load_default_context() - commit_id = self.request.matchdict['commit_id'] - comment_id = self.request.matchdict['comment_id'] + commit_id = self.request.matchdict["commit_id"] + comment_id = self.request.matchdict["comment_id"] comment = ChangesetComment.get_or_404(comment_id) if comment.immutable: # don't allow deleting comments that are immutable raise HTTPForbidden() - is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name) - super_admin = h.HasPermissionAny('hg.admin')() - comment_owner = (comment.author.user_id == self._rhodecode_db_user.user_id) + is_repo_admin = h.HasRepoPermissionAny("repository.admin")(self.db_repo_name) + super_admin = h.HasPermissionAny("hg.admin")() + comment_owner = comment.author.user_id == self._rhodecode_db_user.user_id is_repo_comment = comment.repo.repo_id == self.db_repo.repo_id comment_repo_admin = is_repo_admin and is_repo_comment if super_admin or comment_owner or comment_repo_admin: - text = self.request.POST.get('text') - version = self.request.POST.get('version') + text = self.request.POST.get("text") + version = self.request.POST.get("version") if text == comment.text: log.warning( - 'Comment(repo): ' - 'Trying to create new version ' - 'with the same comment body {}'.format( + "Comment(repo): Trying to create new version with the same comment body {}".format( comment_id, ) ) @@ -741,8 +725,7 @@ class RepoCommitsView(RepoAppView): version = int(version) else: log.warning( - 'Comment(repo): Wrong version type {} {} ' - 'for comment {}'.format( + "Comment(repo): Wrong version type {} {} for comment {}".format( version, type(version), comment_id, @@ -766,29 +749,26 @@ class RepoCommitsView(RepoAppView): if not comment.draft: commit = self.db_repo.get_commit(commit_id) CommentsModel().trigger_commit_comment_hook( - self.db_repo, self._rhodecode_user, 'edit', - data={'comment': comment, 'commit': commit}) + self.db_repo, self._rhodecode_user, "edit", data={"comment": comment, "commit": commit} + ) Session().commit() return { - 'comment_history_id': comment_history.comment_history_id, - 'comment_id': comment.comment_id, - 'comment_version': comment_history.version, - 'comment_author_username': comment_history.author.username, - 'comment_author_gravatar': h.gravatar_url(comment_history.author.email, 16, request=self.request), - 'comment_created_on': h.age_component(comment_history.created_on, - time_is_local=True), + "comment_history_id": comment_history.comment_history_id, + "comment_id": comment.comment_id, + "comment_version": comment_history.version, + "comment_author_username": comment_history.author.username, + "comment_author_gravatar": h.gravatar_url(comment_history.author.email, 16, request=self.request), + "comment_created_on": h.age_component(comment_history.created_on, time_is_local=True), } else: - log.warning('No permissions for user %s to edit comment_id: %s', - self._rhodecode_db_user, comment_id) + log.warning("No permissions for user %s to edit comment_id: %s", self._rhodecode_db_user, comment_id) raise HTTPNotFound() @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commit_data(self): - commit_id = self.request.matchdict['commit_id'] + commit_id = self.request.matchdict["commit_id"] self.load_default_context() try: @@ -797,10 +777,9 @@ class RepoCommitsView(RepoAppView): return EmptyCommit(message=str(e)) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commit_children(self): - commit_id = self.request.matchdict['commit_id'] + commit_id = self.request.matchdict["commit_id"] self.load_default_context() try: @@ -813,10 +792,9 @@ class RepoCommitsView(RepoAppView): return result @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_commit_parents(self): - commit_id = self.request.matchdict['commit_id'] + commit_id = self.request.matchdict["commit_id"] self.load_default_context() try: diff --git a/rhodecode/apps/repository/views/repo_compare.py b/rhodecode/apps/repository/views/repo_compare.py index 69448255..11945816 100644 --- a/rhodecode/apps/repository/views/repo_compare.py +++ b/rhodecode/apps/repository/views/repo_compare.py @@ -33,8 +33,11 @@ from rhodecode.lib.utils import safe_str from rhodecode.lib.utils2 import str2bool from rhodecode.lib.view_utils import parse_path_ref, get_commit_from_ref_name from rhodecode.lib.vcs.exceptions import ( - EmptyRepositoryError, RepositoryError, RepositoryRequirementError, - NodeDoesNotExistError) + EmptyRepositoryError, + RepositoryError, + RepositoryRequirementError, + NodeDoesNotExistError, +) from rhodecode.model.db import Repository, ChangesetStatus log = logging.getLogger(__name__) @@ -46,8 +49,7 @@ class RepoCompareView(RepoAppView): c.rhodecode_repo = self.rhodecode_vcs_repo return c - def _get_commit_or_redirect( - self, ref, ref_type, repo, redirect_after=True, partial=False): + def _get_commit_or_redirect(self, ref, ref_type, repo, redirect_after=True, partial=False): """ This is a safe way to get a commit. If an error occurs it redirects to a commit with a proper message. If partial is set @@ -59,30 +61,26 @@ class RepoCompareView(RepoAppView): except EmptyRepositoryError: if not redirect_after: return repo.scm_instance().EMPTY_COMMIT - h.flash(h.literal(_('There are no commits yet')), - category='warning') + h.flash(h.literal(_("There are no commits yet")), category="warning") if not partial: - raise HTTPFound( - h.route_path('repo_summary', repo_name=repo.repo_name)) + raise HTTPFound(h.route_path("repo_summary", repo_name=repo.repo_name)) raise HTTPBadRequest() except RepositoryError as e: log.exception(safe_str(e)) - h.flash(h.escape(safe_str(e)), category='warning') + h.flash(h.escape(safe_str(e)), category="warning") if not partial: - raise HTTPFound( - h.route_path('repo_summary', repo_name=repo.repo_name)) + raise HTTPFound(h.route_path("repo_summary", repo_name=repo.repo_name)) raise HTTPBadRequest() @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def compare_select(self): _ = self.request.translate c = self.load_default_context() source_repo = self.db_repo_name - target_repo = self.request.GET.get('target_repo', source_repo) + target_repo = self.request.GET.get("target_repo", source_repo) c.source_repo = Repository.get_by_repo_name(source_repo) c.target_repo = Repository.get_by_repo_name(target_repo) @@ -94,7 +92,7 @@ class RepoCompareView(RepoAppView): c.collapse_all_commits = False c.diffset = None c.limited_diff = False - c.source_ref = c.target_ref = _('Select commit') + c.source_ref = c.target_ref = _("Select commit") c.source_ref_type = "" c.target_ref_type = "" c.commit_statuses = ChangesetStatus.STATUSES @@ -104,36 +102,34 @@ class RepoCompareView(RepoAppView): return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def compare(self): _ = self.request.translate c = self.load_default_context() - source_ref_type = self.request.matchdict['source_ref_type'] - source_ref = self.request.matchdict['source_ref'] - target_ref_type = self.request.matchdict['target_ref_type'] - target_ref = self.request.matchdict['target_ref'] + source_ref_type = self.request.matchdict["source_ref_type"] + source_ref = self.request.matchdict["source_ref"] + target_ref_type = self.request.matchdict["target_ref_type"] + target_ref = self.request.matchdict["target_ref"] # source_ref will be evaluated in source_repo source_repo_name = self.db_repo_name source_path, source_id = parse_path_ref(source_ref) # target_ref will be evaluated in target_repo - target_repo_name = self.request.GET.get('target_repo', source_repo_name) - target_path, target_id = parse_path_ref( - target_ref, default_path=self.request.GET.get('f_path', '')) + target_repo_name = self.request.GET.get("target_repo", source_repo_name) + target_path, target_id = parse_path_ref(target_ref, default_path=self.request.GET.get("f_path", "")) # if merge is True # Show what changes since the shared ancestor commit of target/source # the source would get if it was merged with target. Only commits # which are in target but not in source will be shown. - merge = str2bool(self.request.GET.get('merge')) + merge = str2bool(self.request.GET.get("merge")) # if merge is False # Show a raw diff of source/target refs even if no ancestor exists # c.fulldiff disables cut_off_limit - c.fulldiff = str2bool(self.request.GET.get('fulldiff')) + c.fulldiff = str2bool(self.request.GET.get("fulldiff")) # fetch global flags of ignore ws or context lines diff_context = diffs.get_diff_context(self.request) @@ -147,33 +143,28 @@ class RepoCompareView(RepoAppView): # swap url for compare_diff page c.swap_url = h.route_path( - 'repo_compare', + "repo_compare", repo_name=target_repo_name, source_ref_type=target_ref_type, source_ref=target_ref, target_repo=source_repo_name, target_ref_type=source_ref_type, target_ref=source_ref, - _query=dict(merge=merge and '1' or '', f_path=target_path)) + _query=dict(merge=merge and "1" or "", f_path=target_path), + ) source_repo = Repository.get_by_repo_name(source_repo_name) target_repo = Repository.get_by_repo_name(target_repo_name) if source_repo is None: - log.error('Could not find the source repo: {}' - .format(source_repo_name)) - h.flash(_('Could not find the source repo: `{}`') - .format(h.escape(source_repo_name)), category='error') - raise HTTPFound( - h.route_path('repo_compare_select', repo_name=self.db_repo_name)) + log.error("Could not find the source repo: {}".format(source_repo_name)) + h.flash(_("Could not find the source repo: `{}`").format(h.escape(source_repo_name)), category="error") + raise HTTPFound(h.route_path("repo_compare_select", repo_name=self.db_repo_name)) if target_repo is None: - log.error('Could not find the target repo: {}' - .format(source_repo_name)) - h.flash(_('Could not find the target repo: `{}`') - .format(h.escape(target_repo_name)), category='error') - raise HTTPFound( - h.route_path('repo_compare_select', repo_name=self.db_repo_name)) + log.error("Could not find the target repo: {}".format(source_repo_name)) + h.flash(_("Could not find the target repo: `{}`").format(h.escape(target_repo_name)), category="error") + raise HTTPFound(h.route_path("repo_compare_select", repo_name=self.db_repo_name)) source_scm = source_repo.scm_instance() target_scm = target_repo.scm_instance() @@ -181,19 +172,17 @@ class RepoCompareView(RepoAppView): source_alias = source_scm.alias target_alias = target_scm.alias if source_alias != target_alias: - msg = _('The comparison of two different kinds of remote repos ' - 'is not available') + msg = _("The comparison of two different kinds of remote repos is not available") log.error(msg) - h.flash(msg, category='error') - raise HTTPFound( - h.route_path('repo_compare_select', repo_name=self.db_repo_name)) + h.flash(msg, category="error") + raise HTTPFound(h.route_path("repo_compare_select", repo_name=self.db_repo_name)) source_commit = self._get_commit_or_redirect( - ref=source_id, ref_type=source_ref_type, repo=source_repo, - partial=partial) + ref=source_id, ref_type=source_ref_type, repo=source_repo, partial=partial + ) target_commit = self._get_commit_or_redirect( - ref=target_id, ref_type=target_ref_type, repo=target_repo, - partial=partial) + ref=target_id, ref_type=target_ref_type, repo=target_repo, partial=partial + ) c.compare_home = False c.source_repo = source_repo @@ -207,25 +196,21 @@ class RepoCompareView(RepoAppView): c.ancestor = None try: - c.commit_ranges = source_scm.compare( - source_commit.raw_id, target_commit.raw_id, - target_scm, merge, pre_load=pre_load) or [] + c.commit_ranges = ( + source_scm.compare(source_commit.raw_id, target_commit.raw_id, target_scm, merge, pre_load=pre_load) + or [] + ) if merge: - c.ancestor = source_scm.get_common_ancestor( - source_commit.raw_id, target_commit.raw_id, target_scm) + c.ancestor = source_scm.get_common_ancestor(source_commit.raw_id, target_commit.raw_id, target_scm) except RepositoryRequirementError: - msg = _('Could not compare repos with different ' - 'large file settings') + msg = _("Could not compare repos with different large file settings") log.error(msg) if partial: return Response(msg) - h.flash(msg, category='error') - raise HTTPFound( - h.route_path('repo_compare_select', - repo_name=self.db_repo_name)) + h.flash(msg, category="error") + raise HTTPFound(h.route_path("repo_compare_select", repo_name=self.db_repo_name)) - c.statuses = self.db_repo.statuses( - [x.raw_id for x in c.commit_ranges]) + c.statuses = self.db_repo.statuses([x.raw_id for x in c.commit_ranges]) # auto collapse if we have more than limit collapse_limit = diffs.DiffProcessor._collapse_commits_over @@ -233,19 +218,18 @@ class RepoCompareView(RepoAppView): if partial: # for PR ajax commits loader if not c.ancestor: - return Response('') # cannot merge if there is no ancestor + return Response("") # cannot merge if there is no ancestor html = render( - 'rhodecode:templates/compare/compare_commits.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/compare/compare_commits.mako", self._get_template_context(c), self.request + ) return Response(html) if c.ancestor: # case we want a simple diff without incoming commits, # previewing what will be merged. # Make the diff on target repo (which is known to have target_ref) - log.debug('Using ancestor %s as source_ref instead of %s', - c.ancestor, source_ref) + log.debug("Using ancestor %s as source_ref instead of %s", c.ancestor, source_ref) source_repo = target_repo source_commit = target_repo.get_commit(commit_id=c.ancestor) @@ -254,36 +238,39 @@ class RepoCompareView(RepoAppView): diff_limit = c.visual.cut_off_limit_diff file_limit = c.visual.cut_off_limit_file - log.debug('calculating diff between ' - 'source_ref:%s and target_ref:%s for repo `%s`', - source_commit, target_commit, - safe_str(source_repo.scm_instance().path)) + log.debug( + "calculating diff between source_ref:%s and target_ref:%s for repo `%s`", + source_commit, + target_commit, + safe_str(source_repo.scm_instance().path), + ) if source_commit.repository != target_commit.repository: - msg = _( "Repositories unrelated. " "Cannot compare commit %(commit1)s from repository %(repo1)s " - "with commit %(commit2)s from repository %(repo2)s.") % { - 'commit1': h.show_id(source_commit), - 'repo1': source_repo.repo_name, - 'commit2': h.show_id(target_commit), - 'repo2': target_repo.repo_name, - } - h.flash(msg, category='error') - raise HTTPFound( - h.route_path('repo_compare_select', - repo_name=self.db_repo_name)) + "with commit %(commit2)s from repository %(repo2)s." + ) % { + "commit1": h.show_id(source_commit), + "repo1": source_repo.repo_name, + "commit2": h.show_id(target_commit), + "repo2": target_repo.repo_name, + } + h.flash(msg, category="error") + raise HTTPFound(h.route_path("repo_compare_select", repo_name=self.db_repo_name)) txt_diff = source_repo.scm_instance().get_diff( - commit1=source_commit, commit2=target_commit, - path=target_path, path1=source_path, - ignore_whitespace=hide_whitespace_changes, context=diff_context) + commit1=source_commit, + commit2=target_commit, + path=target_path, + path1=source_path, + ignore_whitespace=hide_whitespace_changes, + context=diff_context, + ) - diff_processor = diffs.DiffProcessor(txt_diff, diff_format='newdiff', - diff_limit=diff_limit, - file_limit=file_limit, - show_full_diff=c.fulldiff) + diff_processor = diffs.DiffProcessor( + txt_diff, diff_format="newdiff", diff_limit=diff_limit, file_limit=file_limit, show_full_diff=c.fulldiff + ) _parsed = diff_processor.prepare() diffset = codeblocks.DiffSet( @@ -292,14 +279,11 @@ class RepoCompareView(RepoAppView): target_repo_name=self.db_repo_name, target_node_getter=codeblocks.diffset_node_getter(target_commit), ) - c.diffset = self.path_filter.render_patchset_filtered( - diffset, _parsed, source_ref, target_ref) + c.diffset = self.path_filter.render_patchset_filtered(diffset, _parsed, source_ref, target_ref) c.preview_mode = merge c.source_commit = source_commit c.target_commit = target_commit - html = render( - 'rhodecode:templates/compare/compare_diff.mako', - self._get_template_context(c), self.request) - return Response(html) \ No newline at end of file + html = render("rhodecode:templates/compare/compare_diff.mako", self._get_template_context(c), self.request) + return Response(html) diff --git a/rhodecode/apps/repository/views/repo_feed.py b/rhodecode/apps/repository/views/repo_feed.py index 0254e5f6..4e0eee55 100644 --- a/rhodecode/apps/repository/views/repo_feed.py +++ b/rhodecode/apps/repository/views/repo_feed.py @@ -26,8 +26,7 @@ from rhodecode.lib.feedgenerator import Rss201rev2Feed, Atom1Feed from rhodecode.lib import audit_logger from rhodecode.lib import rc_cache from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.diffs import DiffProcessor, LimitedDiffContainer from rhodecode.lib.utils2 import str2bool, safe_int, md5_safe from rhodecode.model.db import UserApiKeys, CacheKey @@ -43,58 +42,55 @@ class RepoFeedView(RepoAppView): def _get_config(self): import rhodecode + config = rhodecode.CONFIG return { - 'language': 'en-us', - 'feed_ttl': '5', # TTL of feed, - 'feed_include_diff': - str2bool(config.get('rss_include_diff', False)), - 'feed_items_per_page': - safe_int(config.get('rss_items_per_page', 20)), - 'feed_diff_limit': - # we need to protect from parsing huge diffs here other way - # we can kill the server - safe_int(config.get('rss_cut_off_limit', 32 * 1024)), + "language": "en-us", + "feed_ttl": "5", # TTL of feed, + "feed_include_diff": str2bool(config.get("rss_include_diff", False)), + "feed_items_per_page": safe_int(config.get("rss_items_per_page", 20)), + "feed_diff_limit": + # we need to protect from parsing huge diffs here other way + # we can kill the server + safe_int(config.get("rss_cut_off_limit", 32 * 1024)), } def _load_defaults(self): _ = self.request.translate config = self._get_config() # common values for feeds - self.description = _('Changes on %s repository') - self.title = _('%s %s feed') % (self.db_repo_name, '%s') + self.description = _("Changes on %s repository") + self.title = _("%s %s feed") % (self.db_repo_name, "%s") self.language = config["language"] self.ttl = config["feed_ttl"] - self.feed_include_diff = config['feed_include_diff'] - self.feed_diff_limit = config['feed_diff_limit'] - self.feed_items_per_page = config['feed_items_per_page'] + self.feed_include_diff = config["feed_include_diff"] + self.feed_diff_limit = config["feed_diff_limit"] + self.feed_items_per_page = config["feed_items_per_page"] def _changes(self, commit): diff = commit.diff() - diff_processor = DiffProcessor(diff, diff_format='newdiff', - diff_limit=self.feed_diff_limit) + diff_processor = DiffProcessor(diff, diff_format="newdiff", diff_limit=self.feed_diff_limit) _parsed = diff_processor.prepare(inline_diff=False) limited_diff = isinstance(_parsed, LimitedDiffContainer) return diff_processor, _parsed, limited_diff def _get_title(self, commit): - return h.chop_at_smart(commit.message, '\n', suffix_if_chopped='...') + return h.chop_at_smart(commit.message, "\n", suffix_if_chopped="...") def _get_description(self, commit): - _renderer = self.request.get_partial_renderer( - 'rhodecode:templates/feed/atom_feed_entry.mako') + _renderer = self.request.get_partial_renderer("rhodecode:templates/feed/atom_feed_entry.mako") diff_processor, parsed_diff, limited_diff = self._changes(commit) filtered_parsed_diff, has_hidden_changes = self.path_filter.filter_patchset(parsed_diff) return _renderer( - 'body', + "body", commit=commit, parsed_diff=filtered_parsed_diff, limited_diff=limited_diff, feed_include_diff=self.feed_include_diff, diff_processor=diff_processor, - has_hidden_changes=has_hidden_changes + has_hidden_changes=has_hidden_changes, ) def _set_timezone(self, date, tzinfo=datetime.UTC): @@ -103,25 +99,21 @@ class RepoFeedView(RepoAppView): return date def _get_commits(self): - pre_load = ['author', 'branch', 'date', 'message', 'parents'] + pre_load = ["author", "branch", "date", "message", "parents"] if self.rhodecode_vcs_repo.is_empty(): return [] collection = self.rhodecode_vcs_repo.get_commits( - branch_name=None, show_hidden=False, pre_load=pre_load, - translate_tags=False) - - return list(collection[-self.feed_items_per_page:]) - - def uid(self, repo_id, commit_id): - return '{}:{}'.format( - md5_safe(repo_id, return_type='str'), - md5_safe(commit_id, return_type='str') + branch_name=None, show_hidden=False, pre_load=pre_load, translate_tags=False ) + return list(collection[-self.feed_items_per_page :]) + + def uid(self, repo_id, commit_id): + return "{}:{}".format(md5_safe(repo_id, return_type="str"), md5_safe(commit_id, return_type="str")) + @LoginRequired(auth_token_access=[UserApiKeys.ROLE_FEED]) - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def atom(self): """ Produce an atom-1.0 feed via feedgenerator module @@ -129,19 +121,18 @@ class RepoFeedView(RepoAppView): self.load_default_context() force_recache = self.get_recache_flag() - cache_namespace_uid = f'repo_feed.{self.db_repo.repo_id}' + cache_namespace_uid = f"repo_feed.{self.db_repo.repo_id}" condition = not (self.path_filter.is_enabled or force_recache) - region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) + region = rc_cache.get_or_create_region("cache_repo", cache_namespace_uid) - @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, - condition=condition) + @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, condition=condition) def generate_atom_feed(repo_id, _repo_name, _commit_id, _feed_type): feed = Atom1Feed( - title=self.title % 'atom', - link=h.route_url('repo_summary', repo_name=_repo_name), + title=self.title % "atom", + link=h.route_url("repo_summary", repo_name=_repo_name), description=self.description % _repo_name, language=self.language, - ttl=self.ttl + ttl=self.ttl, ) for commit in reversed(self._get_commits()): @@ -151,24 +142,21 @@ class RepoFeedView(RepoAppView): title=self._get_title(commit), author_name=commit.author, description=self._get_description(commit), - link=h.route_url( - 'repo_commit', repo_name=_repo_name, - commit_id=commit.raw_id), - pubdate=date,) + link=h.route_url("repo_commit", repo_name=_repo_name, commit_id=commit.raw_id), + pubdate=date, + ) - return feed.content_type, feed.writeString('utf-8') + return feed.content_type, feed.writeString("utf-8") - commit_id = self.db_repo.changeset_cache.get('raw_id') - content_type, feed = generate_atom_feed( - self.db_repo.repo_id, self.db_repo.repo_name, commit_id, 'atom') + commit_id = self.db_repo.changeset_cache.get("raw_id") + content_type, feed = generate_atom_feed(self.db_repo.repo_id, self.db_repo.repo_name, commit_id, "atom") response = Response(feed) response.content_type = content_type return response @LoginRequired(auth_token_access=[UserApiKeys.ROLE_FEED]) - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def rss(self): """ Produce an rss2 feed via feedgenerator module @@ -176,19 +164,18 @@ class RepoFeedView(RepoAppView): self.load_default_context() force_recache = self.get_recache_flag() - cache_namespace_uid = f'repo_feed.{self.db_repo.repo_id}' + cache_namespace_uid = f"repo_feed.{self.db_repo.repo_id}" condition = not (self.path_filter.is_enabled or force_recache) - region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) + region = rc_cache.get_or_create_region("cache_repo", cache_namespace_uid) - @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, - condition=condition) + @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, condition=condition) def generate_rss_feed(repo_id, _repo_name, _commit_id, _feed_type): feed = Rss201rev2Feed( - title=self.title % 'rss', - link=h.route_url('repo_summary', repo_name=_repo_name), + title=self.title % "rss", + link=h.route_url("repo_summary", repo_name=_repo_name), description=self.description % _repo_name, language=self.language, - ttl=self.ttl + ttl=self.ttl, ) for commit in reversed(self._get_commits()): @@ -198,15 +185,13 @@ class RepoFeedView(RepoAppView): title=self._get_title(commit), author_name=commit.author, description=self._get_description(commit), - link=h.route_url( - 'repo_commit', repo_name=_repo_name, - commit_id=commit.raw_id), - pubdate=date,) - return feed.content_type, feed.writeString('utf-8') + link=h.route_url("repo_commit", repo_name=_repo_name, commit_id=commit.raw_id), + pubdate=date, + ) + return feed.content_type, feed.writeString("utf-8") - commit_id = self.db_repo.changeset_cache.get('raw_id') - content_type, feed = generate_rss_feed( - self.db_repo.repo_id, self.db_repo.repo_name, commit_id, 'rss') + commit_id = self.db_repo.changeset_cache.get("raw_id") + content_type, feed = generate_rss_feed(self.db_repo.repo_id, self.db_repo.repo_name, commit_id, "rss") response = Response(feed) response.content_type = content_type diff --git a/rhodecode/apps/repository/views/repo_files.py b/rhodecode/apps/repository/views/repo_files.py index 0e3f0878..54338235 100644 --- a/rhodecode/apps/repository/views/repo_files.py +++ b/rhodecode/apps/repository/views/repo_files.py @@ -157,7 +157,7 @@ class RepoFilesView(RepoAppView): _ = self.request.translate if not is_head: - message = _("Cannot modify file. " "Given commit `{}` is not head of a branch.").format(commit_id) + message = _("Cannot modify file. Given commit `{}` is not head of a branch.").format(commit_id) h.flash(message, category="warning") if json_mode: @@ -808,7 +808,7 @@ class RepoFilesView(RepoAppView): safe_path = f_name.replace('"', '\\"') encoded_path = urllib.parse.quote(f_name) - headers = f"attachment; " f'filename="{safe_path}"; ' f"filename*=UTF-8''{encoded_path}" + headers = f"attachment; filename=\"{safe_path}\"; filename*=UTF-8''{encoded_path}" return header_safe_str(headers) @@ -993,9 +993,7 @@ class RepoFilesView(RepoAppView): if self.rhodecode_vcs_repo.alias == "svn": adjusted_f_path = RepoFilesView.adjust_file_path_for_svn(f_path, self.rhodecode_vcs_repo) if adjusted_f_path != f_path: - log.debug( - 'Recognized svn tag or branch in file "%s", using svn ' "specific symbolic references", f_path - ) + log.debug('Recognized svn tag or branch in file "%s", using svn specific symbolic references', f_path) f_path = adjusted_f_path symbolic_reference = self._symbolic_reference_svn @@ -1393,7 +1391,7 @@ class RepoFilesView(RepoAppView): except NonRelativePathError: log.exception("Non Relative path found") h.flash( - _("The location specified must be a relative path and must not " "contain .. in the path"), + _("The location specified must be a relative path and must not contain .. in the path"), category="warning", ) raise HTTPFound(default_redirect_url) @@ -1490,7 +1488,7 @@ class RepoFilesView(RepoAppView): except NonRelativePathError: log.exception("Non Relative path found") - error = _("The location specified must be a relative path and must not " "contain .. in the path") + error = _("The location specified must be a relative path and must not contain .. in the path") h.flash(error, category="warning") return {"error": error, "redirect_url": default_redirect_url} diff --git a/rhodecode/apps/repository/views/repo_forks.py b/rhodecode/apps/repository/views/repo_forks.py index fd1a19f6..cda60db3 100644 --- a/rhodecode/apps/repository/views/repo_forks.py +++ b/rhodecode/apps/repository/views/repo_forks.py @@ -29,8 +29,13 @@ from pyramid.response import Response from rhodecode import events from rhodecode.apps._base import RepoAppView, DataGridAppView from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, - HasRepoPermissionAny, HasPermissionAnyDecorator, CSRFRequired) + LoginRequired, + HasRepoPermissionAnyDecorator, + NotAnonymous, + HasRepoPermissionAny, + HasPermissionAnyDecorator, + CSRFRequired, +) import rhodecode.lib.helpers as h from rhodecode.lib.str_utils import safe_str from rhodecode.lib.celerylib.utils import get_task_id @@ -44,14 +49,11 @@ log = logging.getLogger(__name__) class RepoForksView(RepoAppView, DataGridAppView): - def load_default_context(self): c = self._get_local_tmpl_context(include_app_defaults=True) c.rhodecode_repo = self.rhodecode_vcs_repo - acl_groups = RepoGroupList( - RepoGroup.query().all(), - perm_set=['group.write', 'group.admin']) + acl_groups = RepoGroupList(RepoGroup.query().all(), perm_set=["group.write", "group.admin"]) c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) c.repo_groups_choices = list(map(lambda k: safe_str(k[0]), c.repo_groups)) @@ -60,64 +62,54 @@ class RepoForksView(RepoAppView, DataGridAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_forks_show_all(self): c = self.load_default_context() return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_forks_data(self): _ = self.request.translate self.load_default_context() - column_map = { - 'fork_name': 'repo_name', - 'fork_date': 'created_on', - 'last_activity': 'updated_on' - } + column_map = {"fork_name": "repo_name", "fork_date": "created_on", "last_activity": "updated_on"} draw, start, limit = self._extract_chunk(self.request) - search_q, order_by, order_dir = self._extract_ordering( - self.request, column_map=column_map) + search_q, order_by, order_dir = self._extract_ordering(self.request, column_map=column_map) - acl_check = HasRepoPermissionAny( - 'repository.read', 'repository.write', 'repository.admin') + acl_check = HasRepoPermissionAny("repository.read", "repository.write", "repository.admin") repo_id = self.db_repo.repo_id allowed_ids = [-1] for f in Repository.query().filter(Repository.fork_id == repo_id): - if acl_check(f.repo_name, 'get forks check'): + if acl_check(f.repo_name, "get forks check"): allowed_ids.append(f.repo_id) - forks_data_total_count = Repository.query()\ - .filter(Repository.fork_id == repo_id)\ - .filter(Repository.repo_id.in_(allowed_ids))\ - .count() + forks_data_total_count = ( + Repository.query().filter(Repository.fork_id == repo_id).filter(Repository.repo_id.in_(allowed_ids)).count() + ) # json generate - base_q = Repository.query()\ - .filter(Repository.fork_id == repo_id)\ - .filter(Repository.repo_id.in_(allowed_ids))\ - + base_q = Repository.query().filter(Repository.fork_id == repo_id).filter(Repository.repo_id.in_(allowed_ids)) if search_q: - like_expression = f'%{safe_str(search_q)}%' - base_q = base_q.filter(or_( - Repository.repo_name.ilike(like_expression), - Repository.description.ilike(like_expression), - )) + like_expression = f"%{safe_str(search_q)}%" + base_q = base_q.filter( + or_( + Repository.repo_name.ilike(like_expression), + Repository.description.ilike(like_expression), + ) + ) forks_data_total_filtered_count = base_q.count() sort_col = getattr(Repository, order_by, None) if sort_col: - if order_dir == 'asc': + if order_dir == "asc": # handle null values properly to order by NULL last - if order_by in ['last_activity']: + if order_by in ["last_activity"]: sort_col = coalesce(sort_col, datetime.date.max) sort_col = sort_col.asc() else: # handle null values properly to order by NULL last - if order_by in ['last_activity']: + if order_by in ["last_activity"]: sort_col = coalesce(sort_col, datetime.date.min) sort_col = sort_col.desc() @@ -128,117 +120,106 @@ class RepoForksView(RepoAppView, DataGridAppView): def fork_actions(fork): url_link = h.route_path( - 'repo_compare', + "repo_compare", repo_name=fork.repo_name, source_ref_type=self.db_repo.landing_ref_type, source_ref=self.db_repo.landing_ref_name, target_ref_type=self.db_repo.landing_ref_type, target_ref=self.db_repo.landing_ref_name, - _query=dict(merge=1, target_repo=f.repo_name)) - return h.link_to(_('Compare fork'), url_link, class_='btn-link') + _query=dict(merge=1, target_repo=f.repo_name), + ) + return h.link_to(_("Compare fork"), url_link, class_="btn-link") def fork_name(fork): - return h.link_to(fork.repo_name, - h.route_path('repo_summary', repo_name=fork.repo_name)) + return h.link_to(fork.repo_name, h.route_path("repo_summary", repo_name=fork.repo_name)) forks_data = [] for fork in fork_list: - forks_data.append({ - "username": h.gravatar_with_user(self.request, fork.user.username), - "fork_name": fork_name(fork), - "description": fork.description_safe, - "fork_date": h.age_component(fork.created_on, time_is_local=True), - "last_activity": h.format_date(fork.updated_on), - "action": fork_actions(fork), - }) + forks_data.append( + { + "username": h.gravatar_with_user(self.request, fork.user.username), + "fork_name": fork_name(fork), + "description": fork.description_safe, + "fork_date": h.age_component(fork.created_on, time_is_local=True), + "last_activity": h.format_date(fork.updated_on), + "action": fork_actions(fork), + } + ) - data = ({ - 'draw': draw, - 'data': forks_data, - 'recordsTotal': forks_data_total_count, - 'recordsFiltered': forks_data_total_filtered_count, - }) + data = { + "draw": draw, + "data": forks_data, + "recordsTotal": forks_data_total_count, + "recordsFiltered": forks_data_total_filtered_count, + } return data @LoginRequired() @NotAnonymous() - @HasPermissionAnyDecorator('hg.admin', PermissionModel.FORKING_ENABLED) - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasPermissionAnyDecorator("hg.admin", PermissionModel.FORKING_ENABLED) + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_fork_new(self): c = self.load_default_context() defaults = RepoModel()._get_defaults(self.db_repo_name) # alter the description to indicate a fork - defaults['description'] = ( - 'fork of repository: {} \n{}'.format( - defaults['repo_name'], defaults['description'])) + defaults["description"] = "fork of repository: {} \n{}".format(defaults["repo_name"], defaults["description"]) # add suffix to fork - defaults['repo_name'] = '%s-fork' % defaults['repo_name'] + defaults["repo_name"] = "%s-fork" % defaults["repo_name"] - data = render('rhodecode:templates/forks/fork.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/forks/fork.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() @NotAnonymous() - @HasPermissionAnyDecorator('hg.admin', PermissionModel.FORKING_ENABLED) - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasPermissionAnyDecorator("hg.admin", PermissionModel.FORKING_ENABLED) + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def repo_fork_create(self): _ = self.request.translate c = self.load_default_context() - _form = RepoForkForm(self.request.translate, - old_data={'repo_type': self.db_repo.repo_type}, - repo_groups=c.repo_groups_choices)() + _form = RepoForkForm( + self.request.translate, old_data={"repo_type": self.db_repo.repo_type}, repo_groups=c.repo_groups_choices + )() post_data = dict(self.request.POST) # forbid injecting other repo by forging a request - post_data['fork_parent_id'] = self.db_repo.repo_id - post_data['landing_rev'] = self.db_repo._landing_revision + post_data["fork_parent_id"] = self.db_repo.repo_id + post_data["landing_rev"] = self.db_repo._landing_revision form_result = {} task_id = None try: form_result = _form.to_python(post_data) - copy_permissions = form_result.get('copy_permissions') + copy_permissions = form_result.get("copy_permissions") # create fork is done sometimes async on celery, db transaction # management is handled there. - task = RepoModel().create_fork( - form_result, c.rhodecode_user.user_id) + task = RepoModel().create_fork(form_result, c.rhodecode_user.user_id) task_id = get_task_id(task) except formencode.Invalid as errors: c.rhodecode_db_repo = self.db_repo - data = render('rhodecode:templates/forks/fork.mako', - self._get_template_context(c), self.request) + data = render("rhodecode:templates/forks/fork.mako", self._get_template_context(c), self.request) html = formencode.htmlfill.render( data, defaults=errors.value, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: - log.exception( - 'Exception while trying to fork the repository %s', self.db_repo_name) - msg = _('An error occurred during repository forking %s') % (self.db_repo_name, ) - h.flash(msg, category='error') - raise HTTPFound(h.route_path('home')) + log.exception("Exception while trying to fork the repository %s", self.db_repo_name) + msg = _("An error occurred during repository forking %s") % (self.db_repo_name,) + h.flash(msg, category="error") + raise HTTPFound(h.route_path("home")) - repo_name = form_result.get('repo_name_full', self.db_repo_name) + repo_name = form_result.get("repo_name_full", self.db_repo_name) affected_user_ids = [self._rhodecode_user.user_id] if copy_permissions: @@ -247,6 +228,4 @@ class RepoForksView(RepoAppView, DataGridAppView): PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound( - h.route_path('repo_creating', repo_name=repo_name, - _query=dict(task_id=task_id))) + raise HTTPFound(h.route_path("repo_creating", repo_name=repo_name, _query=dict(task_id=task_id))) diff --git a/rhodecode/apps/repository/views/repo_maintainance.py b/rhodecode/apps/repository/views/repo_maintainance.py index f2db5c13..e7062c98 100644 --- a/rhodecode/apps/repository/views/repo_maintainance.py +++ b/rhodecode/apps/repository/views/repo_maintainance.py @@ -19,7 +19,6 @@ import logging - from rhodecode.apps._base import RepoAppView from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib import repo_maintenance @@ -33,19 +32,19 @@ class RepoMaintenanceView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_maintenance(self): c = self.load_default_context() - c.active = 'maintenance' + c.active = "maintenance" maintenance = repo_maintenance.RepoMaintenance() c.executable_tasks = maintenance.get_tasks_for_repo(self.db_repo) return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_maintenance_execute(self): c = self.load_default_context() - c.active = 'maintenance' + c.active = "maintenance" _ = self.request.translate maintenance = repo_maintenance.RepoMaintenance() diff --git a/rhodecode/apps/repository/views/repo_permissions.py b/rhodecode/apps/repository/views/repo_permissions.py index db019f57..e8dd9776 100644 --- a/rhodecode/apps/repository/views/repo_permissions.py +++ b/rhodecode/apps/repository/views/repo_permissions.py @@ -23,8 +23,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import RepoAppView from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.lib.utils2 import str2bool from rhodecode.model.db import User from rhodecode.model.forms import RepoPermsForm @@ -36,87 +35,81 @@ log = logging.getLogger(__name__) class RepoSettingsPermissionsView(RepoAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def edit_permissions(self): _ = self.request.translate c = self.load_default_context() - c.active = 'permissions' - if self.request.GET.get('branch_permissions'): - h.flash(_('Explicitly add user or user group with write or higher ' - 'permission to modify their branch permissions.'), - category='notice') + c.active = "permissions" + if self.request.GET.get("branch_permissions"): + h.flash( + _( + "Explicitly add user or user group with write or higher " + "permission to modify their branch permissions." + ), + category="notice", + ) return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_permissions_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'permissions' + c.active = "permissions" data = self.request.POST # store private flag outside of HTML to verify if we can modify # default user permissions, prevents submission of FAKE post data # into the form for private repos - data['repo_private'] = self.db_repo.private + data["repo_private"] = self.db_repo.private form = RepoPermsForm(self.request.translate)().to_python(data) changes = RepoModel().update_permissions( - self.db_repo_name, form['perm_additions'], form['perm_updates'], - form['perm_deletions']) + self.db_repo_name, form["perm_additions"], form["perm_updates"], form["perm_deletions"] + ) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } audit_logger.store_web( - 'repo.edit.permissions', action_data=action_data, - user=self._rhodecode_user, repo=self.db_repo) + "repo.edit.permissions", action_data=action_data, user=self._rhodecode_user, repo=self.db_repo + ) Session().commit() - h.flash(_('Repository access permissions updated'), category='success') + h.flash(_("Repository access permissions updated"), category="success") affected_user_ids = None - if changes.get('default_user_changed', False): + if changes.get("default_user_changed", False): # if we change the default user, we need to flush everyone permissions affected_user_ids = User.get_all_user_ids() - PermissionModel().flush_user_permission_caches( - changes, affected_user_ids=affected_user_ids) + PermissionModel().flush_user_permission_caches(changes, affected_user_ids=affected_user_ids) - raise HTTPFound( - h.route_path('edit_repo_perms', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("edit_repo_perms", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_permissions_set_private_repo(self): _ = self.request.translate self.load_default_context() - private_flag = str2bool(self.request.POST.get('private')) - changes = { - 'repo_private': private_flag - } + private_flag = str2bool(self.request.POST.get("private")) + changes = {"repo_private": private_flag} try: repo = RepoModel().get(self.db_repo.repo_id) RepoModel().update(repo, **changes) Session().commit() - h.flash(_('Repository `{}` private mode set successfully').format(self.db_repo_name), - category='success') + h.flash(_("Repository `{}` private mode set successfully").format(self.db_repo_name), category="success") except Exception: log.exception("Exception during update of repository") - h.flash(_('Error occurred during update of repository {}').format( - self.db_repo_name), category='error') + h.flash(_("Error occurred during update of repository {}").format(self.db_repo_name), category="error") - return { - 'redirect_url': h.route_path('edit_repo_perms', repo_name=self.db_repo_name), - 'private': private_flag - } + return {"redirect_url": h.route_path("edit_repo_perms", repo_name=self.db_repo_name), "private": private_flag} diff --git a/rhodecode/apps/repository/views/repo_pull_requests.py b/rhodecode/apps/repository/views/repo_pull_requests.py index ee434ec7..9b24e585 100644 --- a/rhodecode/apps/repository/views/repo_pull_requests.py +++ b/rhodecode/apps/repository/views/repo_pull_requests.py @@ -22,8 +22,7 @@ import collections import formencode import formencode.htmlfill import peppercorn -from pyramid.httpexceptions import ( - HTTPFound, HTTPNotFound, HTTPForbidden, HTTPBadRequest, HTTPConflict) +from pyramid.httpexceptions import HTTPFound, HTTPNotFound, HTTPForbidden, HTTPBadRequest, HTTPConflict from pyramid.renderers import render @@ -35,18 +34,27 @@ from rhodecode.lib.diffs import load_cached_diff, cache_diff, diff_cache_exist from rhodecode.lib.exceptions import CommentVersionMismatch from rhodecode.lib import ext_json from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAny, HasRepoPermissionAnyDecorator, - NotAnonymous, CSRFRequired) + LoginRequired, + HasRepoPermissionAny, + HasRepoPermissionAnyDecorator, + NotAnonymous, + CSRFRequired, +) from rhodecode.lib.utils2 import str2bool, safe_str, safe_int, aslist, retry -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, UpdateFailureReason, unicode_to_reference) -from rhodecode.lib.vcs.exceptions import ( - CommitDoesNotExistError, RepositoryRequirementError, EmptyRepositoryError) +from rhodecode.lib.vcs.backends.base import EmptyCommit, UpdateFailureReason, unicode_to_reference +from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError, RepositoryRequirementError, EmptyRepositoryError from rhodecode.model.changeset_status import ChangesetStatusModel from rhodecode.model.comment import CommentsModel from rhodecode.model.db import ( - func, false, or_, PullRequest, ChangesetComment, ChangesetStatus, Repository, - PullRequestReviewers) + func, + false, + or_, + PullRequest, + ChangesetComment, + ChangesetStatus, + Repository, + PullRequestReviewers, +) from rhodecode.model.forms import PullRequestForm from rhodecode.model.meta import Session from rhodecode.model.pull_request import PullRequestModel, MergeCheck @@ -56,56 +64,70 @@ log = logging.getLogger(__name__) class RepoPullRequestsView(RepoAppView, DataGridAppView): - def load_default_context(self): c = self._get_local_tmpl_context(include_app_defaults=True) c.REVIEW_STATUS_APPROVED = ChangesetStatus.STATUS_APPROVED c.REVIEW_STATUS_REJECTED = ChangesetStatus.STATUS_REJECTED # backward compat., we use for OLD PRs a plain renderer - c.renderer = 'plain' + c.renderer = "plain" return c - def _get_pull_requests_list( - self, repo_name, source, filter_type, opened_by, statuses): - + def _get_pull_requests_list(self, repo_name, source, filter_type, opened_by, statuses): draw, start, limit = self._extract_chunk(self.request) search_q, order_by, order_dir = self._extract_ordering(self.request) - _render = self.request.get_partial_renderer( - 'rhodecode:templates/data_table/_dt_elements.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/data_table/_dt_elements.mako") # pagination - if filter_type == 'awaiting_review': + if filter_type == "awaiting_review": pull_requests = PullRequestModel().get_awaiting_review( repo_name, - search_q=search_q, statuses=statuses, - offset=start, length=limit, order_by=order_by, order_dir=order_dir) + search_q=search_q, + statuses=statuses, + offset=start, + length=limit, + order_by=order_by, + order_dir=order_dir, + ) pull_requests_total_count = PullRequestModel().count_awaiting_review( - repo_name, - search_q=search_q, statuses=statuses) - elif filter_type == 'awaiting_my_review': + repo_name, search_q=search_q, statuses=statuses + ) + elif filter_type == "awaiting_my_review": pull_requests = PullRequestModel().get_awaiting_my_review( - repo_name, self._rhodecode_user.user_id, - search_q=search_q, statuses=statuses, - offset=start, length=limit, order_by=order_by, order_dir=order_dir) + repo_name, + self._rhodecode_user.user_id, + search_q=search_q, + statuses=statuses, + offset=start, + length=limit, + order_by=order_by, + order_dir=order_dir, + ) pull_requests_total_count = PullRequestModel().count_awaiting_my_review( - repo_name, self._rhodecode_user.user_id, - search_q=search_q, statuses=statuses) + repo_name, self._rhodecode_user.user_id, search_q=search_q, statuses=statuses + ) else: pull_requests = PullRequestModel().get_all( - repo_name, search_q=search_q, source=source, opened_by=opened_by, - statuses=statuses, offset=start, length=limit, - order_by=order_by, order_dir=order_dir) + repo_name, + search_q=search_q, + source=source, + opened_by=opened_by, + statuses=statuses, + offset=start, + length=limit, + order_by=order_by, + order_dir=order_dir, + ) pull_requests_total_count = PullRequestModel().count_all( - repo_name, search_q=search_q, source=source, statuses=statuses, - opened_by=opened_by) + repo_name, search_q=search_q, source=source, statuses=statuses, opened_by=opened_by + ) data = [] comments_model = CommentsModel() for pr in pull_requests: comments_count = comments_model.get_all_comments( - self.db_repo.repo_id, pull_request=pr, - include_drafts=False, count_only=True) + self.db_repo.repo_id, pull_request=pr, include_drafts=False, count_only=True + ) review_statuses = pr.reviewers_statuses(user=self._rhodecode_db_user) my_review_status = ChangesetStatus.STATUS_NOT_REVIEWED @@ -113,87 +135,88 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): _review_obj, _user, _reasons, _mandatory, statuses = review_statuses my_review_status = statuses[0][1].status - data.append({ - 'name': _render('pullrequest_name', - pr.pull_request_id, pr.pull_request_state, - pr.work_in_progress, pr.target_repo.repo_name, - short=True), - 'name_raw': pr.pull_request_id, - 'status': _render('pullrequest_status', - pr.calculated_review_status()), - 'my_status': _render('pullrequest_status', - my_review_status), - 'title': _render('pullrequest_title', pr.title, pr.description), - 'pr_flow': _render('pullrequest_commit_flow', pr), - 'description': h.escape(pr.description), - 'updated_on': _render('pullrequest_updated_on', - h.datetime_to_time(pr.updated_on), - pr.versions_count), - 'updated_on_raw': h.datetime_to_time(pr.updated_on), - 'created_on': _render('pullrequest_updated_on', - h.datetime_to_time(pr.created_on)), - 'created_on_raw': h.datetime_to_time(pr.created_on), - 'state': pr.pull_request_state, - 'author': _render('pullrequest_author', - pr.author.full_contact, ), - 'author_raw': pr.author.full_name, - 'comments': _render('pullrequest_comments', comments_count), - 'comments_raw': comments_count, - 'closed': pr.is_closed(), - }) + data.append( + { + "name": _render( + "pullrequest_name", + pr.pull_request_id, + pr.pull_request_state, + pr.work_in_progress, + pr.target_repo.repo_name, + short=True, + ), + "name_raw": pr.pull_request_id, + "status": _render("pullrequest_status", pr.calculated_review_status()), + "my_status": _render("pullrequest_status", my_review_status), + "title": _render("pullrequest_title", pr.title, pr.description), + "pr_flow": _render("pullrequest_commit_flow", pr), + "description": h.escape(pr.description), + "updated_on": _render( + "pullrequest_updated_on", h.datetime_to_time(pr.updated_on), pr.versions_count + ), + "updated_on_raw": h.datetime_to_time(pr.updated_on), + "created_on": _render("pullrequest_updated_on", h.datetime_to_time(pr.created_on)), + "created_on_raw": h.datetime_to_time(pr.created_on), + "state": pr.pull_request_state, + "author": _render( + "pullrequest_author", + pr.author.full_contact, + ), + "author_raw": pr.author.full_name, + "comments": _render("pullrequest_comments", comments_count), + "comments_raw": comments_count, + "closed": pr.is_closed(), + } + ) - data = ({ - 'draw': draw, - 'data': data, - 'recordsTotal': pull_requests_total_count, - 'recordsFiltered': pull_requests_total_count, - }) + data = { + "draw": draw, + "data": data, + "recordsTotal": pull_requests_total_count, + "recordsFiltered": pull_requests_total_count, + } return data @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pull_request_list(self): c = self.load_default_context() req_get = self.request.GET - c.source = str2bool(req_get.get('source')) - c.closed = str2bool(req_get.get('closed')) - c.my = str2bool(req_get.get('my')) - c.awaiting_review = str2bool(req_get.get('awaiting_review')) - c.awaiting_my_review = str2bool(req_get.get('awaiting_my_review')) + c.source = str2bool(req_get.get("source")) + c.closed = str2bool(req_get.get("closed")) + c.my = str2bool(req_get.get("my")) + c.awaiting_review = str2bool(req_get.get("awaiting_review")) + c.awaiting_my_review = str2bool(req_get.get("awaiting_my_review")) - c.active = 'open' + c.active = "open" if c.my: - c.active = 'my' + c.active = "my" if c.closed: - c.active = 'closed' + c.active = "closed" if c.awaiting_review and not c.source: - c.active = 'awaiting' + c.active = "awaiting" if c.source and not c.awaiting_review: - c.active = 'source' + c.active = "source" if c.awaiting_my_review: - c.active = 'awaiting_my' + c.active = "awaiting_my" return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pull_request_list_data(self): self.load_default_context() # additional filters req_get = self.request.GET - source = str2bool(req_get.get('source')) - closed = str2bool(req_get.get('closed')) - my = str2bool(req_get.get('my')) - awaiting_review = str2bool(req_get.get('awaiting_review')) - awaiting_my_review = str2bool(req_get.get('awaiting_my_review')) + source = str2bool(req_get.get("source")) + closed = str2bool(req_get.get("closed")) + my = str2bool(req_get.get("my")) + awaiting_review = str2bool(req_get.get("awaiting_review")) + awaiting_my_review = str2bool(req_get.get("awaiting_my_review")) - filter_type = 'awaiting_review' if awaiting_review \ - else 'awaiting_my_review' if awaiting_my_review \ - else None + filter_type = "awaiting_review" if awaiting_review else "awaiting_my_review" if awaiting_my_review else None opened_by = None if my: @@ -204,23 +227,32 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): statuses = [PullRequest.STATUS_CLOSED] data = self._get_pull_requests_list( - repo_name=self.db_repo_name, source=source, - filter_type=filter_type, opened_by=opened_by, statuses=statuses) + repo_name=self.db_repo_name, source=source, filter_type=filter_type, opened_by=opened_by, statuses=statuses + ) return data def _is_diff_cache_enabled(self, target_repo): - caching_enabled = self._get_general_setting( - target_repo, 'rhodecode_diff_cache') - log.debug('Diff caching enabled: %s', caching_enabled) + caching_enabled = self._get_general_setting(target_repo, "rhodecode_diff_cache") + log.debug("Diff caching enabled: %s", caching_enabled) return caching_enabled - def _get_diffset(self, source_repo_name, source_repo, - ancestor_commit, - source_ref_id, target_ref_id, - target_commit, source_commit, diff_limit, file_limit, - fulldiff, hide_whitespace_changes, diff_context, use_ancestor=True): - + def _get_diffset( + self, + source_repo_name, + source_repo, + ancestor_commit, + source_ref_id, + target_ref_id, + target_commit, + source_commit, + diff_limit, + file_limit, + fulldiff, + hide_whitespace_changes, + diff_context, + use_ancestor=True, + ): target_commit_final = target_commit source_commit_final = source_commit @@ -230,11 +262,12 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): target_commit_final = ancestor_commit vcs_diff = PullRequestModel().get_diff( - source_repo, source_ref_id, target_ref_id, - hide_whitespace_changes, diff_context) + source_repo, source_ref_id, target_ref_id, hide_whitespace_changes, diff_context + ) - diff_processor = diffs.DiffProcessor(vcs_diff, diff_format='newdiff', diff_limit=diff_limit, - file_limit=file_limit, show_full_diff=fulldiff) + diff_processor = diffs.DiffProcessor( + vcs_diff, diff_format="newdiff", diff_limit=diff_limit, file_limit=file_limit, show_full_diff=fulldiff + ) _parsed = diff_processor.prepare() @@ -244,32 +277,39 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): source_node_getter=codeblocks.diffset_node_getter(target_commit_final), target_node_getter=codeblocks.diffset_node_getter(source_commit_final), ) - diffset = self.path_filter.render_patchset_filtered( - diffset, _parsed, target_ref_id, source_ref_id) + diffset = self.path_filter.render_patchset_filtered(diffset, _parsed, target_ref_id, source_ref_id) return diffset - def _get_range_diffset(self, source_scm, source_repo, - commit1, commit2, diff_limit, file_limit, - fulldiff, hide_whitespace_changes, diff_context): + def _get_range_diffset( + self, + source_scm, + source_repo, + commit1, + commit2, + diff_limit, + file_limit, + fulldiff, + hide_whitespace_changes, + diff_context, + ): vcs_diff = source_scm.get_diff( - commit1, commit2, - ignore_whitespace=hide_whitespace_changes, - context=diff_context) + commit1, commit2, ignore_whitespace=hide_whitespace_changes, context=diff_context + ) - diff_processor = diffs.DiffProcessor(vcs_diff, diff_format='newdiff', - diff_limit=diff_limit, - file_limit=file_limit, show_full_diff=fulldiff) + diff_processor = diffs.DiffProcessor( + vcs_diff, diff_format="newdiff", diff_limit=diff_limit, file_limit=file_limit, show_full_diff=fulldiff + ) _parsed = diff_processor.prepare() diffset = codeblocks.DiffSet( repo_name=source_repo.repo_name, source_node_getter=codeblocks.diffset_node_getter(commit1), - target_node_getter=codeblocks.diffset_node_getter(commit2)) + target_node_getter=codeblocks.diffset_node_getter(commit2), + ) - diffset = self.path_filter.render_patchset_filtered( - diffset, _parsed, commit1.raw_id, commit2.raw_id) + diffset = self.path_filter.render_patchset_filtered(diffset, _parsed, commit1.raw_id, commit2.raw_id) return diffset @@ -284,8 +324,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): general_comments = q # pick comments we want to render at current version - c.comment_versions = comments_model.aggregate_comments( - general_comments, versions, c.at_version_num) + c.comment_versions = comments_model.aggregate_comments(general_comments, versions, c.at_version_num) # INLINE COMMENTS with versions # q = comments_model._all_inline_comments_of_pull_request(pull_request) @@ -294,73 +333,66 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): q = q.filter(ChangesetComment.draft == false()) inline_comments = q - c.inline_versions = comments_model.aggregate_comments( - inline_comments, versions, c.at_version_num, inline=True) + c.inline_versions = comments_model.aggregate_comments(inline_comments, versions, c.at_version_num, inline=True) # Comments inline+general if c.at_version: - c.inline_comments_flat = c.inline_versions[c.at_version_num]['display'] - c.comments = c.comment_versions[c.at_version_num]['display'] + c.inline_comments_flat = c.inline_versions[c.at_version_num]["display"] + c.comments = c.comment_versions[c.at_version_num]["display"] else: - c.inline_comments_flat = c.inline_versions[c.at_version_num]['until'] - c.comments = c.comment_versions[c.at_version_num]['until'] + c.inline_comments_flat = c.inline_versions[c.at_version_num]["until"] + c.comments = c.comment_versions[c.at_version_num]["until"] return general_comments, inline_comments @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pull_request_show(self): _ = self.request.translate c = self.load_default_context() - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) pull_request_id = pull_request.pull_request_id c.state_progressing = pull_request.is_state_changing() c.pr_broadcast_channel = channelstream.pr_channel(pull_request) _new_state = { - 'created': PullRequest.STATE_CREATED, - }.get(self.request.GET.get('force_state')) - can_force_state = c.is_super_admin or HasRepoPermissionAny('repository.admin')(c.repo_name) + "created": PullRequest.STATE_CREATED, + }.get(self.request.GET.get("force_state")) + can_force_state = c.is_super_admin or HasRepoPermissionAny("repository.admin")(c.repo_name) if can_force_state and _new_state: with pull_request.set_state(PullRequest.STATE_UPDATING, final_state=_new_state): - h.flash( - _('Pull Request state was force changed to `{}`').format(_new_state), - category='success') + h.flash(_("Pull Request state was force changed to `{}`").format(_new_state), category="success") Session().commit() - raise HTTPFound(h.route_path( - 'pullrequest_show', repo_name=self.db_repo_name, - pull_request_id=pull_request_id)) + raise HTTPFound( + h.route_path("pullrequest_show", repo_name=self.db_repo_name, pull_request_id=pull_request_id) + ) - version = self.request.GET.get('version') - from_version = self.request.GET.get('from_version') or version - merge_checks = self.request.GET.get('merge_checks') - c.fulldiff = str2bool(self.request.GET.get('fulldiff')) - force_refresh = str2bool(self.request.GET.get('force_refresh')) - c.range_diff_on = self.request.GET.get('range-diff') == "1" + version = self.request.GET.get("version") + from_version = self.request.GET.get("from_version") or version + merge_checks = self.request.GET.get("merge_checks") + c.fulldiff = str2bool(self.request.GET.get("fulldiff")) + force_refresh = str2bool(self.request.GET.get("force_refresh")) + c.range_diff_on = self.request.GET.get("range-diff") == "1" # fetch global flags of ignore ws or context lines diff_context = diffs.get_diff_context(self.request) hide_whitespace_changes = diffs.get_diff_whitespace_flag(self.request) - (pull_request_latest, - pull_request_at_ver, - pull_request_display_obj, - at_version) = PullRequestModel().get_pr_version( - pull_request_id, version=version) + (pull_request_latest, pull_request_at_ver, pull_request_display_obj, at_version) = ( + PullRequestModel().get_pr_version(pull_request_id, version=version) + ) pr_closed = pull_request_latest.is_closed() if pr_closed and (version or from_version): # not allow browsing versions for closed PR - raise HTTPFound(h.route_path( - 'pullrequest_show', repo_name=self.db_repo_name, - pull_request_id=pull_request_id)) + raise HTTPFound( + h.route_path("pullrequest_show", repo_name=self.db_repo_name, pull_request_id=pull_request_id) + ) versions = pull_request_display_obj.versions() @@ -370,25 +402,17 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): c.changes = collections.OrderedDict() c.at_version = at_version - c.at_version_num = (at_version - if at_version and at_version != PullRequest.LATEST_VER - else None) + c.at_version_num = at_version if at_version and at_version != PullRequest.LATEST_VER else None - c.at_version_index = ChangesetComment.get_index_from_version( - c.at_version_num, versions) + c.at_version_index = ChangesetComment.get_index_from_version(c.at_version_num, versions) - (prev_pull_request_latest, - prev_pull_request_at_ver, - prev_pull_request_display_obj, - prev_at_version) = PullRequestModel().get_pr_version( - pull_request_id, version=from_version) + (prev_pull_request_latest, prev_pull_request_at_ver, prev_pull_request_display_obj, prev_at_version) = ( + PullRequestModel().get_pr_version(pull_request_id, version=from_version) + ) c.from_version = prev_at_version - c.from_version_num = (prev_at_version - if prev_at_version and prev_at_version != PullRequest.LATEST_VER - else None) - c.from_version_index = ChangesetComment.get_index_from_version( - c.from_version_num, versions) + c.from_version_num = prev_at_version if prev_at_version and prev_at_version != PullRequest.LATEST_VER else None + c.from_version_index = ChangesetComment.get_index_from_version(c.from_version_num, versions) # define if we're in COMPARE mode or VIEW at version mode compare = at_version != prev_at_version @@ -396,8 +420,11 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): # pull_requests repo_name we opened it against # i.e., target_repo must match if self.db_repo_name != pull_request_at_ver.target_repo.repo_name: - log.warning('Mismatch between the current repo: %s, and target %s', - self.db_repo_name, pull_request_at_ver.target_repo.repo_name) + log.warning( + "Mismatch between the current repo: %s, and target %s", + self.db_repo_name, + pull_request_at_ver.target_repo.repo_name, + ) raise HTTPNotFound() c.shadow_clone_url = PullRequestModel().get_shadow_clone_url(pull_request_at_ver) @@ -418,34 +445,37 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): c.allowed_to_comment = False c.allowed_to_close = False else: - can_change_status = PullRequestModel().check_user_change_status( - pull_request_at_ver, self._rhodecode_user) + can_change_status = PullRequestModel().check_user_change_status(pull_request_at_ver, self._rhodecode_user) c.allowed_to_change_status = can_change_status and not pr_closed - c.allowed_to_update = PullRequestModel().check_user_update( - pull_request_latest, self._rhodecode_user) and not pr_closed - c.allowed_to_merge = PullRequestModel().check_user_merge( - pull_request_latest, self._rhodecode_user) and not pr_closed - c.allowed_to_delete = PullRequestModel().check_user_delete( - pull_request_latest, self._rhodecode_user) and not pr_closed + c.allowed_to_update = ( + PullRequestModel().check_user_update(pull_request_latest, self._rhodecode_user) and not pr_closed + ) + c.allowed_to_merge = ( + PullRequestModel().check_user_merge(pull_request_latest, self._rhodecode_user) and not pr_closed + ) + c.allowed_to_delete = ( + PullRequestModel().check_user_delete(pull_request_latest, self._rhodecode_user) and not pr_closed + ) c.allowed_to_comment = not pr_closed c.allowed_to_close = c.allowed_to_merge and not pr_closed c.forbid_adding_reviewers = False - if pull_request_latest.reviewer_data and \ - 'rules' in pull_request_latest.reviewer_data: - rules = pull_request_latest.reviewer_data['rules'] or {} + if pull_request_latest.reviewer_data and "rules" in pull_request_latest.reviewer_data: + rules = pull_request_latest.reviewer_data["rules"] or {} try: - c.forbid_adding_reviewers = rules.get('forbid_adding_reviewers') + c.forbid_adding_reviewers = rules.get("forbid_adding_reviewers") except Exception: pass # check merge capabilities _merge_check = MergeCheck.validate( - pull_request_latest, auth_user=self._rhodecode_user, + pull_request_latest, + auth_user=self._rhodecode_user, translator=self.request.translate, - force_shadow_repo_refresh=force_refresh) + force_shadow_repo_refresh=force_refresh, + ) c.pr_merge_errors = _merge_check.error_details c.pr_merge_possible = not _merge_check.failed @@ -453,13 +483,11 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): c.pr_merge_source_commit = _merge_check.source_commit c.pr_merge_target_commit = _merge_check.target_commit - c.pr_merge_info = MergeCheck.get_merge_conditions( - pull_request_latest, translator=self.request.translate) + c.pr_merge_info = MergeCheck.get_merge_conditions(pull_request_latest, translator=self.request.translate) c.pull_request_review_status = _merge_check.review_status if merge_checks: - self.request.override_renderer = \ - 'rhodecode:templates/pullrequests/pullrequest_merge_checks.mako' + self.request.override_renderer = "rhodecode:templates/pullrequests/pullrequest_merge_checks.mako" return self._get_template_context(c) c.reviewers_count = pull_request.reviewers_count @@ -467,22 +495,24 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): # reviewers and statuses c.pull_request_default_reviewers_data_json = ext_json.str_json(pull_request.reviewer_data) - c.pull_request_set_reviewers_data_json = collections.OrderedDict({'reviewers': []}) - c.pull_request_set_observers_data_json = collections.OrderedDict({'observers': []}) + c.pull_request_set_reviewers_data_json = collections.OrderedDict({"reviewers": []}) + c.pull_request_set_observers_data_json = collections.OrderedDict({"observers": []}) # reviewers for review_obj, member, reasons, mandatory, status in pull_request_at_ver.reviewers_statuses(): member_reviewer = h.reviewer_as_json( - member, reasons=reasons, mandatory=mandatory, + member, + reasons=reasons, + mandatory=mandatory, role=review_obj.role, - user_group=review_obj.rule_user_group_data() + user_group=review_obj.rule_user_group_data(), ) current_review_status = status[0][1].status if status else ChangesetStatus.STATUS_NOT_REVIEWED - member_reviewer['review_status'] = current_review_status - member_reviewer['review_status_label'] = h.commit_status_lbl(current_review_status) - member_reviewer['allowed_to_update'] = c.allowed_to_update - c.pull_request_set_reviewers_data_json['reviewers'].append(member_reviewer) + member_reviewer["review_status"] = current_review_status + member_reviewer["review_status_label"] = h.commit_status_lbl(current_review_status) + member_reviewer["allowed_to_update"] = c.allowed_to_update + c.pull_request_set_reviewers_data_json["reviewers"].append(member_reviewer) c.pull_request_set_reviewers_data_json = ext_json.str_json(c.pull_request_set_reviewers_data_json) @@ -491,40 +521,35 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): for observer_obj, member in pull_request_at_ver.observers(): observer_ids.append(observer_obj.user_id) member_observer = h.reviewer_as_json( - member, reasons=[], mandatory=False, + member, + reasons=[], + mandatory=False, role=observer_obj.role, - user_group=observer_obj.rule_user_group_data() + user_group=observer_obj.rule_user_group_data(), ) - member_observer['allowed_to_update'] = c.allowed_to_update - c.pull_request_set_observers_data_json['observers'].append(member_observer) + member_observer["allowed_to_update"] = c.allowed_to_update + c.pull_request_set_observers_data_json["observers"].append(member_observer) c.pull_request_set_observers_data_json = ext_json.str_json(c.pull_request_set_observers_data_json) c.status_change_disabled = self._rhodecode_user.user_id in observer_ids - general_comments, inline_comments = \ - self.register_comments_vars(c, pull_request_latest, versions) + general_comments, inline_comments = self.register_comments_vars(c, pull_request_latest, versions) # TODOs - c.unresolved_comments = CommentsModel() \ - .get_pull_request_unresolved_todos(pull_request_latest) - c.resolved_comments = CommentsModel() \ - .get_pull_request_resolved_todos(pull_request_latest) + c.unresolved_comments = CommentsModel().get_pull_request_unresolved_todos(pull_request_latest) + c.resolved_comments = CommentsModel().get_pull_request_resolved_todos(pull_request_latest) # Drafts - c.draft_comments = CommentsModel().get_pull_request_drafts( - self._rhodecode_db_user.user_id, - pull_request_latest) + c.draft_comments = CommentsModel().get_pull_request_drafts(self._rhodecode_db_user.user_id, pull_request_latest) # if we use version, then do not show later comments # than current version - display_inline_comments = collections.defaultdict( - lambda: collections.defaultdict(list)) + display_inline_comments = collections.defaultdict(lambda: collections.defaultdict(list)) for co in inline_comments: if c.at_version_num: # pick comments that are at least UPTO given version, so we # don't render comments for higher version - should_render = co.pull_request_version_id and \ - co.pull_request_version_id <= c.at_version_num + should_render = co.pull_request_version_id and co.pull_request_version_id <= c.at_version_num else: # showing all, for 'latest' should_render = True @@ -547,10 +572,10 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): # despite opening commits for bookmarks/branches/tags, we always # convert this to rev to prevent changes after bookmark or branch change - c.source_ref_type = 'rev' + c.source_ref_type = "rev" c.source_ref = source_ref_id - c.target_ref_type = 'rev' + c.target_ref_type = "rev" c.target_ref = target_ref_id c.source_repo = source_repo @@ -568,7 +593,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): try: shadow_scm = pull_request_latest.get_shadow_repo() except Exception: - log.debug('Failed to get shadow repo', exc_info=True) + log.debug("Failed to get shadow repo", exc_info=True) # try first the existing source_repo, and then shadow # repo if we can obtain one commits_source_repo = source_scm @@ -585,9 +610,17 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): cache_path = self.rhodecode_vcs_repo.get_create_shadow_cache_pr_path(target_repo) cache_file_path = diff_cache_exist( - cache_path, 'pull_request', pull_request_id, version_normalized, - from_version_normalized, source_ref_id, target_ref_id, - hide_whitespace_changes, diff_context, c.fulldiff) + cache_path, + "pull_request", + pull_request_id, + version_normalized, + from_version_normalized, + source_ref_id, + target_ref_id, + hide_whitespace_changes, + diff_context, + c.fulldiff, + ) caching_enabled = self._is_diff_cache_enabled(c.target_repo) force_recache = self.get_recache_flag() @@ -597,26 +630,25 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): cached_diff = load_cached_diff(cache_file_path) has_proper_commit_cache = ( - cached_diff and cached_diff.get('commits') - and len(cached_diff.get('commits', [])) == 5 - and cached_diff.get('commits')[0] - and cached_diff.get('commits')[3]) + cached_diff + and cached_diff.get("commits") + and len(cached_diff.get("commits", [])) == 5 + and cached_diff.get("commits")[0] + and cached_diff.get("commits")[3] + ) if not force_recache and not c.range_diff_on and has_proper_commit_cache: - diff_commit_cache = \ - (ancestor_commit, commit_cache, missing_requirements, - source_commit, target_commit) = cached_diff['commits'] + diff_commit_cache = (ancestor_commit, commit_cache, missing_requirements, source_commit, target_commit) = ( + cached_diff["commits"] + ) else: # NOTE(marcink): we reach potentially unreachable errors when a PR has # merge errors resulting in potentially hidden commits in the shadow repo. - maybe_unreachable = _merge_check.MERGE_CHECK in _merge_check.error_details \ - and _merge_check.merge_response - maybe_unreachable = maybe_unreachable \ - and _merge_check.merge_response.metadata.get('unresolved_files') + maybe_unreachable = _merge_check.MERGE_CHECK in _merge_check.error_details and _merge_check.merge_response + maybe_unreachable = maybe_unreachable and _merge_check.merge_response.metadata.get("unresolved_files") log.debug("Using unreachable commits due to MERGE_CHECK in merge simulation") - diff_commit_cache = \ - (ancestor_commit, commit_cache, missing_requirements, - source_commit, target_commit) = self.get_commits( + diff_commit_cache = (ancestor_commit, commit_cache, missing_requirements, source_commit, target_commit) = ( + self.get_commits( commits_source_repo, pull_request_at_ver, source_commit, @@ -625,7 +657,9 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): target_commit, target_ref_id, target_scm, - maybe_unreachable=maybe_unreachable) + maybe_unreachable=maybe_unreachable, + ) + ) # register our commit range for comm in commit_cache.values(): @@ -633,8 +667,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): c.missing_requirements = missing_requirements c.ancestor_commit = ancestor_commit - c.statuses = source_repo.statuses( - [x.raw_id for x in c.commit_ranges]) + c.statuses = source_repo.statuses([x.raw_id for x in c.commit_ranges]) # auto collapse if we have more than limit collapse_limit = diffs.DiffProcessor._collapse_commits_over @@ -648,10 +681,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): file_limit = c.visual.cut_off_limit_file c.missing_commits = False - if (c.missing_requirements - or isinstance(source_commit, EmptyCommit) - or source_commit == target_commit): - + if c.missing_requirements or isinstance(source_commit, EmptyCommit) or source_commit == target_commit: c.missing_commits = True else: c.inline_comments = display_inline_comments @@ -660,44 +690,49 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): if from_version_normalized != version_normalized: use_ancestor = False - has_proper_diff_cache = cached_diff and cached_diff.get('commits') + has_proper_diff_cache = cached_diff and cached_diff.get("commits") if not force_recache and has_proper_diff_cache: - c.diffset = cached_diff['diff'] + c.diffset = cached_diff["diff"] else: try: c.diffset = self._get_diffset( - c.source_repo.repo_name, commits_source_repo, + c.source_repo.repo_name, + commits_source_repo, c.ancestor_commit, - source_ref_id, target_ref_id, - target_commit, source_commit, - diff_limit, file_limit, c.fulldiff, - hide_whitespace_changes, diff_context, - use_ancestor=use_ancestor + source_ref_id, + target_ref_id, + target_commit, + source_commit, + diff_limit, + file_limit, + c.fulldiff, + hide_whitespace_changes, + diff_context, + use_ancestor=use_ancestor, ) # save cached diff if caching_enabled: cache_diff(cache_file_path, c.diffset, diff_commit_cache) except CommitDoesNotExistError: - log.exception('Failed to generate diffset') + log.exception("Failed to generate diffset") c.missing_commits = True if not c.missing_commits: - c.limited_diff = c.diffset.limited_diff # calculate removed files that are bound to comments comment_deleted_files = [ - fname for fname in display_inline_comments - if fname not in c.diffset.file_stats] + fname for fname in display_inline_comments if fname not in c.diffset.file_stats + ] c.deleted_files_comments = collections.defaultdict(dict) for fname, per_line_comments in display_inline_comments.items(): if fname in comment_deleted_files: - c.deleted_files_comments[fname]['stats'] = 0 - c.deleted_files_comments[fname]['comments'] = list() + c.deleted_files_comments[fname]["stats"] = 0 + c.deleted_files_comments[fname]["comments"] = list() for lno, comments in per_line_comments.items(): - c.deleted_files_comments[fname]['comments'].extend(comments) + c.deleted_files_comments[fname]["comments"].extend(comments) # maybe calculate the range diff if c.range_diff_on: @@ -710,21 +745,27 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): commit1 = commit.first_parent range_diff_cache_file_path = diff_cache_exist( - cache_path, 'diff', commit.raw_id, - ign_whitespace_lcl, context_lcl, c.fulldiff) + cache_path, "diff", commit.raw_id, ign_whitespace_lcl, context_lcl, c.fulldiff + ) cached_diff = None if caching_enabled: cached_diff = load_cached_diff(range_diff_cache_file_path) - has_proper_diff_cache = cached_diff and cached_diff.get('diff') + has_proper_diff_cache = cached_diff and cached_diff.get("diff") if not force_recache and has_proper_diff_cache: - diffset = cached_diff['diff'] + diffset = cached_diff["diff"] else: diffset = self._get_range_diffset( - commits_source_repo, source_repo, - commit1, commit2, diff_limit, file_limit, - c.fulldiff, ign_whitespace_lcl, context_lcl + commits_source_repo, + source_repo, + commit1, + commit2, + diff_limit, + file_limit, + c.fulldiff, + ign_whitespace_lcl, + context_lcl, ) # save cached diff @@ -748,8 +789,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): old_commit_ids = prev_obj.revisions new_commit_ids = cur_obj.revisions - commit_changes = PullRequestModel()._calculate_commit_id_changes( - old_commit_ids, new_commit_ids) + commit_changes = PullRequestModel()._calculate_commit_id_changes(old_commit_ids, new_commit_ids) c.commit_changes_summary = commit_changes # calculate the diff for commits between versions @@ -758,10 +798,9 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): def mark(cs, fw): return list(h.itertools.zip_longest([], cs, fillvalue=fw)) - for c_type, raw_id in mark(commit_changes.added, 'a') \ - + mark(commit_changes.removed, 'r') \ - + mark(commit_changes.common, 'c'): - + for c_type, raw_id in ( + mark(commit_changes.added, "a") + mark(commit_changes.removed, "r") + mark(commit_changes.common, "c") + ): if raw_id in commit_cache: commit = commit_cache[raw_id] else: @@ -770,15 +809,12 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): except CommitDoesNotExistError: # in case we fail getting the commit, still use a dummy commit # for display in commit diff - commit = h.AttributeDict( - {'raw_id': raw_id, - 'message': 'EMPTY or MISSING COMMIT'}) + commit = h.AttributeDict({"raw_id": raw_id, "message": "EMPTY or MISSING COMMIT"}) c.commit_changes.append([c_type, commit]) # current user review statuses for each version c.review_versions = {} - is_reviewer = PullRequestModel().is_user_reviewer( - pull_request, self._rhodecode_user) + is_reviewer = PullRequestModel().is_user_reviewer(pull_request, self._rhodecode_user) if is_reviewer: for co in general_comments: if co.author.user_id == self._rhodecode_user.user_id: @@ -790,10 +826,17 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): return self._get_template_context(c) def get_commits( - self, commits_source_repo, pull_request_at_ver, source_commit, - source_ref_id, source_scm, target_commit, target_ref_id, target_scm, - maybe_unreachable=False): - + self, + commits_source_repo, + pull_request_at_ver, + source_commit, + source_ref_id, + source_scm, + target_commit, + target_ref_id, + target_scm, + maybe_unreachable=False, + ): commit_cache = collections.OrderedDict() missing_requirements = False @@ -801,26 +844,23 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): pre_load = ["author", "date", "message", "branch", "parents"] pull_request_commits = pull_request_at_ver.revisions - log.debug('Loading %s commits from %s', - len(pull_request_commits), commits_source_repo) + log.debug("Loading %s commits from %s", len(pull_request_commits), commits_source_repo) for rev in pull_request_commits: - comm = commits_source_repo.get_commit(commit_id=rev, pre_load=pre_load, - maybe_unreachable=maybe_unreachable) + comm = commits_source_repo.get_commit( + commit_id=rev, pre_load=pre_load, maybe_unreachable=maybe_unreachable + ) commit_cache[comm.raw_id] = comm # Order here matters, we first need to get target, and then # the source - target_commit = commits_source_repo.get_commit( - commit_id=safe_str(target_ref_id)) + target_commit = commits_source_repo.get_commit(commit_id=safe_str(target_ref_id)) - source_commit = commits_source_repo.get_commit( - commit_id=safe_str(source_ref_id), maybe_unreachable=True) + source_commit = commits_source_repo.get_commit(commit_id=safe_str(source_ref_id), maybe_unreachable=True) except CommitDoesNotExistError: - log.warning('Failed to get commit from `{}` repo'.format( - commits_source_repo), exc_info=True) + log.warning("Failed to get commit from `{}` repo".format(commits_source_repo), exc_info=True) except RepositoryRequirementError: - log.warning('Failed to get all required data from repo', exc_info=True) + log.warning("Failed to get all required data from repo", exc_info=True) missing_requirements = True pr_ancestor_id = pull_request_at_ver.common_ancestor_id @@ -838,15 +878,12 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): try: self.db_repo.scm_instance().get_commit() except EmptyRepositoryError: - h.flash(h.literal(_('There are no commits yet')), - category='warning') - raise HTTPFound( - h.route_path('repo_summary', repo_name=self.db_repo.repo_name)) + h.flash(h.literal(_("There are no commits yet")), category="warning") + raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo.repo_name)) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pull_request_new(self): _ = self.request.translate c = self.load_default_context() @@ -854,20 +891,22 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): self.assure_not_empty_repo() source_repo = self.db_repo - commit_id = self.request.GET.get('commit') - branch_ref = self.request.GET.get('branch') - bookmark_ref = self.request.GET.get('bookmark') + commit_id = self.request.GET.get("commit") + branch_ref = self.request.GET.get("branch") + bookmark_ref = self.request.GET.get("bookmark") try: source_repo_data = PullRequestModel().generate_repo_data( - source_repo, commit_id=commit_id, - branch=branch_ref, bookmark=bookmark_ref, - translator=self.request.translate) + source_repo, + commit_id=commit_id, + branch=branch_ref, + bookmark=bookmark_ref, + translator=self.request.translate, + ) except CommitDoesNotExistError as e: log.exception(e) - h.flash(_('Commit does not exist'), 'error') - raise HTTPFound( - h.route_path('pullrequest_new', repo_name=source_repo.repo_name)) + h.flash(_("Commit does not exist"), "error") + raise HTTPFound(h.route_path("pullrequest_new", repo_name=source_repo.repo_name)) default_target_repo = source_repo @@ -877,24 +916,21 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): # change default if we have a parent repo default_target_repo = source_repo.parent - target_repo_data = PullRequestModel().generate_repo_data( - default_target_repo, translator=self.request.translate) + target_repo_data = PullRequestModel().generate_repo_data(default_target_repo, translator=self.request.translate) - selected_source_ref = source_repo_data['refs']['selected_ref'] - title_source_ref = '' + selected_source_ref = source_repo_data["refs"]["selected_ref"] + title_source_ref = "" if selected_source_ref: - title_source_ref = selected_source_ref.split(':', 2)[1] + title_source_ref = selected_source_ref.split(":", 2)[1] c.default_title = PullRequestModel().generate_pullrequest_title( - source=source_repo.repo_name, - source_ref=title_source_ref, - target=default_target_repo.repo_name + source=source_repo.repo_name, source_ref=title_source_ref, target=default_target_repo.repo_name ) c.default_repo_data = { - 'source_repo_name': source_repo.repo_name, - 'source_refs_json': ext_json.str_json(source_repo_data), - 'target_repo_name': default_target_repo.repo_name, - 'target_refs_json': ext_json.str_json(target_repo_data), + "source_repo_name": source_repo.repo_name, + "source_refs_json": ext_json.str_json(source_repo_data), + "target_repo_name": default_target_repo.repo_name, + "target_refs_json": ext_json.str_json(target_repo_data), } c.default_source_ref = selected_source_ref @@ -902,43 +938,39 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pull_request_repo_refs(self): self.load_default_context() - target_repo_name = self.request.matchdict['target_repo_name'] + target_repo_name = self.request.matchdict["target_repo_name"] repo = Repository.get_by_repo_name(target_repo_name) if not repo: raise HTTPNotFound() - target_perm = HasRepoPermissionAny( - 'repository.read', 'repository.write', 'repository.admin')( - target_repo_name) + target_perm = HasRepoPermissionAny("repository.read", "repository.write", "repository.admin")(target_repo_name) if not target_perm: raise HTTPNotFound() - return PullRequestModel().generate_repo_data( - repo, translator=self.request.translate) + return PullRequestModel().generate_repo_data(repo, translator=self.request.translate) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pullrequest_repo_targets(self): _ = self.request.translate - filter_query = self.request.GET.get('query') + filter_query = self.request.GET.get("query") # get the parents parent_target_repos = [] if self.db_repo.parent: - parents_query = Repository.query() \ - .order_by(func.length(Repository.repo_name)) \ + parents_query = ( + Repository.query() + .order_by(func.length(Repository.repo_name)) .filter(Repository.fork_id == self.db_repo.parent.repo_id) + ) if filter_query: - ilike_expression = f'%{safe_str(filter_query)}%' - parents_query = parents_query.filter( - Repository.repo_name.ilike(ilike_expression)) + ilike_expression = f"%{safe_str(filter_query)}%" + parents_query = parents_query.filter(Repository.repo_name.ilike(ilike_expression)) parents = parents_query.limit(20).all() for parent in parents: @@ -947,16 +979,20 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): parent_target_repos.append(parent) # get other forks, and repo itself - query = Repository.query() \ - .order_by(func.length(Repository.repo_name)) \ + query = ( + Repository.query() + .order_by(func.length(Repository.repo_name)) .filter( - or_(Repository.repo_id == self.db_repo.repo_id, # repo itself - Repository.fork_id == self.db_repo.repo_id) # forks of this repo - ) \ + or_( + Repository.repo_id == self.db_repo.repo_id, # repo itself + Repository.fork_id == self.db_repo.repo_id, + ) # forks of this repo + ) .filter(~Repository.repo_id.in_([x.repo_id for x in parent_target_repos])) + ) if filter_query: - ilike_expression = f'%{safe_str(filter_query)}%' + ilike_expression = f"%{safe_str(filter_query)}%" query = query.filter(Repository.repo_name.ilike(ilike_expression)) limit = max(20 - len(parent_target_repos), 5) # not less then 5 @@ -967,148 +1003,119 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): repos = [] # This checks permissions to the repositories for obj in ScmModel().get_repos(all_target_repos): - repos.append({ - 'id': obj['name'], - 'text': obj['name'], - 'type': 'repo', - 'repo_id': obj['dbrepo']['repo_id'], - 'repo_type': obj['dbrepo']['repo_type'], - 'private': obj['dbrepo']['private'], + repos.append( + { + "id": obj["name"], + "text": obj["name"], + "type": "repo", + "repo_id": obj["dbrepo"]["repo_id"], + "repo_type": obj["dbrepo"]["repo_type"], + "private": obj["dbrepo"]["private"], + } + ) - }) - - data = { - 'more': False, - 'results': [{ - 'text': _('Repositories'), - 'children': repos - }] if repos else [] - } + data = {"more": False, "results": [{"text": _("Repositories"), "children": repos}] if repos else []} return data @classmethod def get_comment_ids(cls, post_data): - return filter(lambda e: e > 0, map(safe_int, aslist(post_data.get('comments'), ','))) + return filter(lambda e: e > 0, map(safe_int, aslist(post_data.get("comments"), ","))) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pullrequest_comments(self): self.load_default_context() - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) pull_request_id = pull_request.pull_request_id - version = self.request.GET.get('version') + version = self.request.GET.get("version") - _render = self.request.get_partial_renderer( - 'rhodecode:templates/base/sidebar.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/base/sidebar.mako") c = _render.get_call_context() - (pull_request_latest, - pull_request_at_ver, - pull_request_display_obj, - at_version) = PullRequestModel().get_pr_version( - pull_request_id, version=version) + (pull_request_latest, pull_request_at_ver, pull_request_display_obj, at_version) = ( + PullRequestModel().get_pr_version(pull_request_id, version=version) + ) versions = pull_request_display_obj.versions() latest_ver = PullRequest.get_pr_display_object(pull_request_latest, pull_request_latest) c.versions = versions + [latest_ver] c.at_version = at_version - c.at_version_num = (at_version - if at_version and at_version != PullRequest.LATEST_VER - else None) + c.at_version_num = at_version if at_version and at_version != PullRequest.LATEST_VER else None self.register_comments_vars(c, pull_request_latest, versions, include_drafts=False) all_comments = c.inline_comments_flat + c.comments existing_ids = self.get_comment_ids(self.request.POST) - return _render('comments_table', all_comments, len(all_comments), - existing_ids=existing_ids) + return _render("comments_table", all_comments, len(all_comments), existing_ids=existing_ids) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pullrequest_todos(self): self.load_default_context() - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) pull_request_id = pull_request.pull_request_id - version = self.request.GET.get('version') + version = self.request.GET.get("version") - _render = self.request.get_partial_renderer( - 'rhodecode:templates/base/sidebar.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/base/sidebar.mako") c = _render.get_call_context() - (pull_request_latest, - pull_request_at_ver, - pull_request_display_obj, - at_version) = PullRequestModel().get_pr_version( - pull_request_id, version=version) + (pull_request_latest, pull_request_at_ver, pull_request_display_obj, at_version) = ( + PullRequestModel().get_pr_version(pull_request_id, version=version) + ) versions = pull_request_display_obj.versions() latest_ver = PullRequest.get_pr_display_object(pull_request_latest, pull_request_latest) c.versions = versions + [latest_ver] c.at_version = at_version - c.at_version_num = (at_version - if at_version and at_version != PullRequest.LATEST_VER - else None) + c.at_version_num = at_version if at_version and at_version != PullRequest.LATEST_VER else None - c.unresolved_comments = CommentsModel() \ - .get_pull_request_unresolved_todos(pull_request, include_drafts=False) - c.resolved_comments = CommentsModel() \ - .get_pull_request_resolved_todos(pull_request, include_drafts=False) + c.unresolved_comments = CommentsModel().get_pull_request_unresolved_todos(pull_request, include_drafts=False) + c.resolved_comments = CommentsModel().get_pull_request_resolved_todos(pull_request, include_drafts=False) all_comments = c.unresolved_comments + c.resolved_comments existing_ids = self.get_comment_ids(self.request.POST) - return _render('comments_table', all_comments, len(c.unresolved_comments), - todo_comments=True, existing_ids=existing_ids) + return _render( + "comments_table", all_comments, len(c.unresolved_comments), todo_comments=True, existing_ids=existing_ids + ) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def pullrequest_drafts(self): self.load_default_context() - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) pull_request_id = pull_request.pull_request_id - version = self.request.GET.get('version') + version = self.request.GET.get("version") - _render = self.request.get_partial_renderer( - 'rhodecode:templates/base/sidebar.mako') + _render = self.request.get_partial_renderer("rhodecode:templates/base/sidebar.mako") c = _render.get_call_context() - (pull_request_latest, - pull_request_at_ver, - pull_request_display_obj, - at_version) = PullRequestModel().get_pr_version( - pull_request_id, version=version) + (pull_request_latest, pull_request_at_ver, pull_request_display_obj, at_version) = ( + PullRequestModel().get_pr_version(pull_request_id, version=version) + ) versions = pull_request_display_obj.versions() latest_ver = PullRequest.get_pr_display_object(pull_request_latest, pull_request_latest) c.versions = versions + [latest_ver] c.at_version = at_version - c.at_version_num = (at_version - if at_version and at_version != PullRequest.LATEST_VER - else None) + c.at_version_num = at_version if at_version and at_version != PullRequest.LATEST_VER else None - c.draft_comments = CommentsModel() \ - .get_pull_request_drafts(self._rhodecode_db_user.user_id, pull_request) + c.draft_comments = CommentsModel().get_pull_request_drafts(self._rhodecode_db_user.user_id, pull_request) all_comments = c.draft_comments existing_ids = self.get_comment_ids(self.request.POST) - return _render('comments_table', all_comments, len(all_comments), - existing_ids=existing_ids, draft_comments=True) + return _render( + "comments_table", all_comments, len(all_comments), existing_ids=existing_ids, draft_comments=True + ) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def pull_request_create(self): _ = self.request.translate @@ -1118,69 +1125,60 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): controls = peppercorn.parse(self.request.POST.items()) try: - form = PullRequestForm( - self.request.translate, self.db_repo.repo_id)() + form = PullRequestForm(self.request.translate, self.db_repo.repo_id)() _form = form.to_python(controls) except formencode.Invalid as errors: - if errors.error_dict.get('revisions'): - msg = 'Revisions: {}'.format(errors.error_dict['revisions']) - elif errors.error_dict.get('pullrequest_title'): - msg = errors.error_dict.get('pullrequest_title') + if errors.error_dict.get("revisions"): + msg = "Revisions: {}".format(errors.error_dict["revisions"]) + elif errors.error_dict.get("pullrequest_title"): + msg = errors.error_dict.get("pullrequest_title") else: - msg = _('Error creating pull request: {}').format(errors) + msg = _("Error creating pull request: {}").format(errors) log.exception(msg) - h.flash(msg, 'error') + h.flash(msg, "error") # would rather just go back to form ... - raise HTTPFound( - h.route_path('pullrequest_new', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("pullrequest_new", repo_name=self.db_repo_name)) - source_repo = _form['source_repo'] - source_ref = _form['source_ref'] - target_repo = _form['target_repo'] - target_ref = _form['target_ref'] - commit_ids = _form['revisions'][::-1] - common_ancestor_id = _form['common_ancestor'] + source_repo = _form["source_repo"] + source_ref = _form["source_ref"] + target_repo = _form["target_repo"] + target_ref = _form["target_ref"] + commit_ids = _form["revisions"][::-1] + common_ancestor_id = _form["common_ancestor"] # find the ancestor for this pr - source_db_repo = Repository.get_by_repo_name(_form['source_repo']) - target_db_repo = Repository.get_by_repo_name(_form['target_repo']) + source_db_repo = Repository.get_by_repo_name(_form["source_repo"]) + target_db_repo = Repository.get_by_repo_name(_form["target_repo"]) if not (source_db_repo or target_db_repo): - h.flash(_('source_repo or target repo not found'), category='error') - raise HTTPFound( - h.route_path('pullrequest_new', repo_name=self.db_repo_name)) + h.flash(_("source_repo or target repo not found"), category="error") + raise HTTPFound(h.route_path("pullrequest_new", repo_name=self.db_repo_name)) # re-check permissions again here # source_repo we must have read permissions - source_perm = HasRepoPermissionAny( - 'repository.read', 'repository.write', 'repository.admin')( - source_db_repo.repo_name) + source_perm = HasRepoPermissionAny("repository.read", "repository.write", "repository.admin")( + source_db_repo.repo_name + ) if not source_perm: - msg = _('Not Enough permissions to source repo `{}`.'.format( - source_db_repo.repo_name)) - h.flash(msg, category='error') + msg = _("Not Enough permissions to source repo `{}`.".format(source_db_repo.repo_name)) + h.flash(msg, category="error") # copy the args back to redirect org_query = self.request.GET.mixed() - raise HTTPFound( - h.route_path('pullrequest_new', repo_name=self.db_repo_name, - _query=org_query)) + raise HTTPFound(h.route_path("pullrequest_new", repo_name=self.db_repo_name, _query=org_query)) # target repo we must have read permissions, and also later on # we want to check branch permissions here - target_perm = HasRepoPermissionAny( - 'repository.read', 'repository.write', 'repository.admin')( - target_db_repo.repo_name) + target_perm = HasRepoPermissionAny("repository.read", "repository.write", "repository.admin")( + target_db_repo.repo_name + ) if not target_perm: - msg = _('Not Enough permissions to target repo `{}`.'.format( - target_db_repo.repo_name)) - h.flash(msg, category='error') + msg = _("Not Enough permissions to target repo `{}`.".format(target_db_repo.repo_name)) + h.flash(msg, category="error") # copy the args back to redirect org_query = self.request.GET.mixed() - raise HTTPFound( - h.route_path('pullrequest_new', repo_name=self.db_repo_name, - _query=org_query)) + raise HTTPFound(h.route_path("pullrequest_new", repo_name=self.db_repo_name, _query=org_query)) source_scm = source_db_repo.scm_instance() target_scm = target_db_repo.scm_instance() @@ -1191,14 +1189,14 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): source_commit = source_scm.get_commit(source_ref_obj.commit_id) target_commit = target_scm.get_commit(target_ref_obj.commit_id) - ancestor = source_scm.get_common_ancestor( - source_commit.raw_id, target_commit.raw_id, target_scm) + ancestor = source_scm.get_common_ancestor(source_commit.raw_id, target_commit.raw_id, target_scm) # recalculate target ref based on ancestor - target_ref = ':'.join((target_ref_obj.type, target_ref_obj.name, ancestor)) + target_ref = ":".join((target_ref_obj.type, target_ref_obj.name, ancestor)) - get_default_reviewers_data, validate_default_reviewers, validate_observers = \ + get_default_reviewers_data, validate_default_reviewers, validate_observers = ( PullRequestModel().get_reviewer_functions() + ) # recalculate reviewers logic, to make sure we can validate this reviewer_rules = get_default_reviewers_data( @@ -1207,22 +1205,21 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): source_ref_obj, target_db_repo, target_ref_obj, - include_diff_info=False) + include_diff_info=False, + ) - reviewers = validate_default_reviewers(_form['review_members'], reviewer_rules) - observers = validate_observers(_form['observer_members'], reviewer_rules) + reviewers = validate_default_reviewers(_form["review_members"], reviewer_rules) + observers = validate_observers(_form["observer_members"], reviewer_rules) - pullrequest_title = _form['pullrequest_title'] + pullrequest_title = _form["pullrequest_title"] title_source_ref = source_ref_obj.name if not pullrequest_title: pullrequest_title = PullRequestModel().generate_pullrequest_title( - source=source_repo, - source_ref=title_source_ref, - target=target_repo + source=source_repo, source_ref=title_source_ref, target=target_repo ) - description = _form['pullrequest_desc'] - description_renderer = _form['description_renderer'] + description = _form["pullrequest_desc"] + description_renderer = _form["description_renderer"] try: pull_request = PullRequestModel().create( @@ -1239,35 +1236,30 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): description=description, description_renderer=description_renderer, reviewer_data=reviewer_rules, - auth_user=self._rhodecode_user + auth_user=self._rhodecode_user, ) Session().commit() - h.flash(_('Successfully opened new pull request'), - category='success') + h.flash(_("Successfully opened new pull request"), category="success") except Exception: - msg = _('Error occurred during creation of this pull request.') + msg = _("Error occurred during creation of this pull request.") log.exception(msg) - h.flash(msg, category='error') + h.flash(msg, category="error") # copy the args back to redirect org_query = self.request.GET.mixed() - raise HTTPFound( - h.route_path('pullrequest_new', repo_name=self.db_repo_name, - _query=org_query)) + raise HTTPFound(h.route_path("pullrequest_new", repo_name=self.db_repo_name, _query=org_query)) raise HTTPFound( - h.route_path('pullrequest_show', repo_name=target_repo, - pull_request_id=pull_request.pull_request_id)) + h.route_path("pullrequest_show", repo_name=target_repo, pull_request_id=pull_request.pull_request_id) + ) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def pull_request_update(self): - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) _ = self.request.translate c = self.load_default_context() @@ -1277,60 +1269,63 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): is_state_changing = pull_request.is_state_changing() if pull_request.is_closed(): - log.debug('update: forbidden because pull request is closed') - msg = _('Cannot update closed pull requests.') - h.flash(msg, category='error') - return {'response': True, - 'redirect_url': redirect_url} + log.debug("update: forbidden because pull request is closed") + msg = _("Cannot update closed pull requests.") + h.flash(msg, category="error") + return {"response": True, "redirect_url": redirect_url} c.pr_broadcast_channel = channelstream.pr_channel(pull_request) # only owner or admin can update it - allowed_to_update = PullRequestModel().check_user_update( - pull_request, self._rhodecode_user) + allowed_to_update = PullRequestModel().check_user_update(pull_request, self._rhodecode_user) if allowed_to_update: controls = peppercorn.parse(self.request.POST.items()) - force_refresh = str2bool(self.request.POST.get('force_refresh', 'false')) - do_update_commits = str2bool(self.request.POST.get('update_commits', 'false')) + force_refresh = str2bool(self.request.POST.get("force_refresh", "false")) + do_update_commits = str2bool(self.request.POST.get("update_commits", "false")) - if 'review_members' in controls: + if "review_members" in controls: self._update_reviewers( c, - pull_request, controls['review_members'], + pull_request, + controls["review_members"], pull_request.reviewer_data, - PullRequestReviewers.ROLE_REVIEWER) - elif 'observer_members' in controls: + PullRequestReviewers.ROLE_REVIEWER, + ) + elif "observer_members" in controls: self._update_reviewers( c, - pull_request, controls['observer_members'], + pull_request, + controls["observer_members"], pull_request.reviewer_data, - PullRequestReviewers.ROLE_OBSERVER) + PullRequestReviewers.ROLE_OBSERVER, + ) elif do_update_commits: if is_state_changing: - log.debug('commits update: forbidden because pull request is in state %s', - pull_request.pull_request_state) - msg = _('Cannot update pull requests commits in state other than `{}`. ' - 'Current state is: `{}`').format( - PullRequest.STATE_CREATED, pull_request.pull_request_state) - h.flash(msg, category='error') - return {'response': True, - 'redirect_url': redirect_url} + log.debug( + "commits update: forbidden because pull request is in state %s", pull_request.pull_request_state + ) + msg = _( + "Cannot update pull requests commits in state other than `{}`. Current state is: `{}`" + ).format(PullRequest.STATE_CREATED, pull_request.pull_request_state) + h.flash(msg, category="error") + return {"response": True, "redirect_url": redirect_url} self._update_commits(c, pull_request) if force_refresh: redirect_url = h.route_path( - 'pullrequest_show', repo_name=self.db_repo_name, + "pullrequest_show", + repo_name=self.db_repo_name, pull_request_id=pull_request.pull_request_id, - _query={"force_refresh": 1}) - elif str2bool(self.request.POST.get('edit_pull_request', 'false')): + _query={"force_refresh": 1}, + ) + elif str2bool(self.request.POST.get("edit_pull_request", "false")): self._edit_pull_request(pull_request) else: - log.error('Unhandled update data.') + log.error("Unhandled update data.") raise HTTPBadRequest() - return {'response': True, - 'redirect_url': redirect_url} + return {"response": True, "redirect_url": redirect_url} raise HTTPForbidden() def _edit_pull_request(self, pull_request): @@ -1342,117 +1337,114 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): try: PullRequestModel().edit( pull_request, - self.request.POST.get('title'), - self.request.POST.get('description'), - self.request.POST.get('description_renderer'), - self._rhodecode_user) + self.request.POST.get("title"), + self.request.POST.get("description"), + self.request.POST.get("description_renderer"), + self._rhodecode_user, + ) except ValueError: - msg = _('Cannot update closed pull requests.') - h.flash(msg, category='error') + msg = _("Cannot update closed pull requests.") + h.flash(msg, category="error") return else: Session().commit() - msg = _('Pull request title & description updated.') - h.flash(msg, category='success') + msg = _("Pull request title & description updated.") + h.flash(msg, category="success") return def _update_commits(self, c, pull_request): _ = self.request.translate - log.debug('pull-request: running update commits actions') + log.debug("pull-request: running update commits actions") @retry(exception=Exception, n_tries=3, delay=2) def commits_update(): - return PullRequestModel().update_commits( - pull_request, self._rhodecode_db_user) + return PullRequestModel().update_commits(pull_request, self._rhodecode_db_user) with pull_request.set_state(PullRequest.STATE_UPDATING): resp = commits_update() # retry x3 if resp.executed: - if resp.target_changed and resp.source_changed: - changed = 'target and source repositories' + changed = "target and source repositories" elif resp.target_changed and not resp.source_changed: - changed = 'target repository' + changed = "target repository" elif not resp.target_changed and resp.source_changed: - changed = 'source repository' + changed = "source repository" else: - changed = 'nothing' + changed = "nothing" - msg = _('Pull request updated to "{source_commit_id}" with ' - '{count_added} added, {count_removed} removed commits. ' - 'Source of changes: {change_source}.') + msg = _( + 'Pull request updated to "{source_commit_id}" with ' + "{count_added} added, {count_removed} removed commits. " + "Source of changes: {change_source}." + ) msg = msg.format( source_commit_id=pull_request.source_ref_parts.commit_id, count_added=len(resp.changes.added), count_removed=len(resp.changes.removed), - change_source=changed) - h.flash(msg, category='success') - channelstream.pr_update_channelstream_push( - self.request, c.pr_broadcast_channel, self._rhodecode_user, msg) + change_source=changed, + ) + h.flash(msg, category="success") + channelstream.pr_update_channelstream_push(self.request, c.pr_broadcast_channel, self._rhodecode_user, msg) else: msg = PullRequestModel.UPDATE_STATUS_MESSAGES[resp.reason] warning_reasons = [ UpdateFailureReason.NO_CHANGE, UpdateFailureReason.WRONG_REF_TYPE, ] - category = 'warning' if resp.reason in warning_reasons else 'error' + category = "warning" if resp.reason in warning_reasons else "error" h.flash(msg, category=category) def _update_reviewers(self, c, pull_request, review_members, reviewer_rules, role): _ = self.request.translate - get_default_reviewers_data, validate_default_reviewers, validate_observers = \ + get_default_reviewers_data, validate_default_reviewers, validate_observers = ( PullRequestModel().get_reviewer_functions() + ) if role == PullRequestReviewers.ROLE_REVIEWER: try: reviewers = validate_default_reviewers(review_members, reviewer_rules) except ValueError as e: - log.error(f'Reviewers Validation: {e}') - h.flash(e, category='error') + log.error(f"Reviewers Validation: {e}") + h.flash(e, category="error") return old_calculated_status = pull_request.calculated_review_status() - PullRequestModel().update_reviewers( - pull_request, reviewers, self._rhodecode_db_user) + PullRequestModel().update_reviewers(pull_request, reviewers, self._rhodecode_db_user) Session().commit() - msg = _('Pull request reviewers updated.') - h.flash(msg, category='success') - channelstream.pr_update_channelstream_push( - self.request, c.pr_broadcast_channel, self._rhodecode_user, msg) + msg = _("Pull request reviewers updated.") + h.flash(msg, category="success") + channelstream.pr_update_channelstream_push(self.request, c.pr_broadcast_channel, self._rhodecode_user, msg) # trigger status changed if change in reviewers changes the status calculated_status = pull_request.calculated_review_status() if old_calculated_status != calculated_status: PullRequestModel().trigger_pull_request_hook( - pull_request, self._rhodecode_user, 'review_status_change', - data={'status': calculated_status}) + pull_request, self._rhodecode_user, "review_status_change", data={"status": calculated_status} + ) elif role == PullRequestReviewers.ROLE_OBSERVER: try: observers = validate_observers(review_members, reviewer_rules) except ValueError as e: - log.error(f'Observers Validation: {e}') - h.flash(e, category='error') + log.error(f"Observers Validation: {e}") + h.flash(e, category="error") return - PullRequestModel().update_observers( - pull_request, observers, self._rhodecode_db_user) + PullRequestModel().update_observers(pull_request, observers, self._rhodecode_db_user) Session().commit() - msg = _('Pull request observers updated.') - h.flash(msg, category='success') - channelstream.pr_update_channelstream_push( - self.request, c.pr_broadcast_channel, self._rhodecode_user, msg) + msg = _("Pull request observers updated.") + h.flash(msg, category="success") + channelstream.pr_update_channelstream_push(self.request, c.pr_broadcast_channel, self._rhodecode_user, msg) @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def pull_request_merge(self): """ @@ -1461,28 +1453,27 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): After successful merging, the pull request is automatically closed, with a relevant comment. """ - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) _ = self.request.translate if pull_request.is_state_changing(): - log.debug('show: forbidden because pull request is in state %s', - pull_request.pull_request_state) - msg = _('Cannot merge pull requests in state other than `{}`. ' - 'Current state is: `{}`').format(PullRequest.STATE_CREATED, - pull_request.pull_request_state) - h.flash(msg, category='error') + log.debug("show: forbidden because pull request is in state %s", pull_request.pull_request_state) + msg = _("Cannot merge pull requests in state other than `{}`. Current state is: `{}`").format( + PullRequest.STATE_CREATED, pull_request.pull_request_state + ) + h.flash(msg, category="error") raise HTTPFound( - h.route_path('pullrequest_show', - repo_name=pull_request.target_repo.repo_name, - pull_request_id=pull_request.pull_request_id)) + h.route_path( + "pullrequest_show", + repo_name=pull_request.target_repo.repo_name, + pull_request_id=pull_request.pull_request_id, + ) + ) self.load_default_context() with pull_request.set_state(PullRequest.STATE_UPDATING): - check = MergeCheck.validate( - pull_request, auth_user=self._rhodecode_user, - translator=self.request.translate) + check = MergeCheck.validate(pull_request, auth_user=self._rhodecode_user, translator=self.request.translate) merge_possible = not check.failed for err_type, error_msg in check.errors: @@ -1491,19 +1482,24 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): if merge_possible: log.debug("Pre-conditions checked, trying to merge.") extras = vcs_operation_context( - self.request.environ, repo_name=pull_request.target_repo.repo_name, - username=self._rhodecode_db_user.username, action='push', - scm=pull_request.target_repo.repo_type) + self.request.environ, + repo_name=pull_request.target_repo.repo_name, + username=self._rhodecode_db_user.username, + action="push", + scm=pull_request.target_repo.repo_type, + ) with pull_request.set_state(PullRequest.STATE_UPDATING): - self._merge_pull_request( - pull_request, self._rhodecode_db_user, extras) + self._merge_pull_request(pull_request, self._rhodecode_db_user, extras) else: log.debug("Pre-conditions failed, NOT merging.") raise HTTPFound( - h.route_path('pullrequest_show', - repo_name=pull_request.target_repo.repo_name, - pull_request_id=pull_request.pull_request_id)) + h.route_path( + "pullrequest_show", + repo_name=pull_request.target_repo.repo_name, + pull_request_id=pull_request.pull_request_id, + ) + ) def _merge_pull_request(self, pull_request, user, extras): _ = self.request.translate @@ -1511,44 +1507,36 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): if merge_resp.executed: log.debug("The merge was successful, closing the pull request.") - PullRequestModel().close_pull_request( - pull_request.pull_request_id, user) + PullRequestModel().close_pull_request(pull_request.pull_request_id, user) Session().commit() - msg = _('Pull request was successfully merged and closed.') - h.flash(msg, category='success') + msg = _("Pull request was successfully merged and closed.") + h.flash(msg, category="success") else: - log.debug( - "The merge was not successful. Merge response: %s", merge_resp) + log.debug("The merge was not successful. Merge response: %s", merge_resp) msg = merge_resp.merge_status_message - h.flash(msg, category='error') + h.flash(msg, category="error") @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def pull_request_delete(self): _ = self.request.translate - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) self.load_default_context() pr_closed = pull_request.is_closed() - allowed_to_delete = PullRequestModel().check_user_delete( - pull_request, self._rhodecode_user) and not pr_closed + allowed_to_delete = PullRequestModel().check_user_delete(pull_request, self._rhodecode_user) and not pr_closed # only owner can delete it ! if allowed_to_delete: PullRequestModel().delete(pull_request, self._rhodecode_user) Session().commit() - h.flash(_('Successfully deleted pull request'), - category='success') - raise HTTPFound(h.route_path('pullrequest_show_all', - repo_name=self.db_repo_name)) + h.flash(_("Successfully deleted pull request"), category="success") + raise HTTPFound(h.route_path("pullrequest_show_all", repo_name=self.db_repo_name)) - log.warning('user %s tried to delete pull request without access', - self._rhodecode_user) + log.warning("user %s tried to delete pull request without access", self._rhodecode_user) raise HTTPNotFound() def _pull_request_comments_create(self, pull_request, comments): @@ -1558,19 +1546,19 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): return pull_request_id = pull_request.pull_request_id - all_drafts = len([x for x in comments if str2bool(x['is_draft'])]) == len(comments) + all_drafts = len([x for x in comments if str2bool(x["is_draft"])]) == len(comments) for entry in comments: c = self.load_default_context() - comment_type = entry['comment_type'] - text = entry['text'] - status = entry['status'] - is_draft = str2bool(entry['is_draft']) - resolves_comment_id = entry['resolves_comment_id'] - close_pull_request = entry['close_pull_request'] - f_path = entry['f_path'] - line_no = entry['line'] - target_elem_id = f'file-{h.safeid(h.safe_str(f_path))}' + comment_type = entry["comment_type"] + text = entry["text"] + status = entry["status"] + is_draft = str2bool(entry["is_draft"]) + resolves_comment_id = entry["resolves_comment_id"] + close_pull_request = entry["close_pull_request"] + f_path = entry["f_path"] + line_no = entry["line"] + target_elem_id = f"file-{h.safeid(h.safe_str(f_path))}" # the logic here should work like following, if we submit close # pr comment, use `close_pull_request_with_comment` function @@ -1578,35 +1566,35 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): if close_pull_request: # only owner or admin or person with write permissions - allowed_to_close = PullRequestModel().check_user_update( - pull_request, self._rhodecode_user) + allowed_to_close = PullRequestModel().check_user_update(pull_request, self._rhodecode_user) if not allowed_to_close: - log.debug('comment: forbidden because not allowed to close ' - 'pull request %s', pull_request_id) + log.debug("comment: forbidden because not allowed to close pull request %s", pull_request_id) raise HTTPForbidden() # This also triggers `review_status_change` comment, status = PullRequestModel().close_pull_request_with_comment( - pull_request, self._rhodecode_user, self.db_repo, message=text, - auth_user=self._rhodecode_user) + pull_request, self._rhodecode_user, self.db_repo, message=text, auth_user=self._rhodecode_user + ) Session().flush() is_inline = comment.is_inline PullRequestModel().trigger_pull_request_hook( - pull_request, self._rhodecode_user, 'comment', - data={'comment': comment}) + pull_request, self._rhodecode_user, "comment", data={"comment": comment} + ) else: # regular comment case, could be inline, or one with status. # for that one we check also permissions # Additionally ENSURE if somehow draft is sent we're then unable to change status - allowed_to_change_status = PullRequestModel().check_user_change_status( - pull_request, self._rhodecode_user) and not is_draft + allowed_to_change_status = ( + PullRequestModel().check_user_change_status(pull_request, self._rhodecode_user) and not is_draft + ) if status and allowed_to_change_status: - message = (_('Status change %(transition_icon)s %(status)s') - % {'transition_icon': '>', - 'status': ChangesetStatus.get_status_lbl(status)}) + message = _("Status change %(transition_icon)s %(status)s") % { + "transition_icon": ">", + "status": ChangesetStatus.get_status_lbl(status), + } text = text or message comment = CommentsModel().create( @@ -1616,10 +1604,10 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): pull_request=pull_request, f_path=f_path, line_no=line_no, - status_change=(ChangesetStatus.get_status_lbl(status) - if status and allowed_to_change_status else None), - status_change_type=(status - if status and allowed_to_change_status else None), + status_change=( + ChangesetStatus.get_status_lbl(status) if status and allowed_to_change_status else None + ), + status_change_type=(status if status and allowed_to_change_status else None), comment_type=comment_type, is_draft=is_draft, resolves_comment_id=resolves_comment_id, @@ -1639,7 +1627,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): status, self._rhodecode_user.user_id, comment, - pull_request=pull_request + pull_request=pull_request, ) Session().flush() @@ -1650,82 +1638,82 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): # skip notifications for drafts if not is_draft: PullRequestModel().trigger_pull_request_hook( - pull_request, self._rhodecode_user, 'comment', - data={'comment': comment}) + pull_request, self._rhodecode_user, "comment", data={"comment": comment} + ) # we now calculate the status of pull request, and based on that # calculation we set the commits status calculated_status = pull_request.calculated_review_status() if old_calculated_status != calculated_status: PullRequestModel().trigger_pull_request_hook( - pull_request, self._rhodecode_user, 'review_status_change', - data={'status': calculated_status}) + pull_request, + self._rhodecode_user, + "review_status_change", + data={"status": calculated_status}, + ) comment_id = comment.comment_id - data[comment_id] = { - 'target_id': target_elem_id - } + data[comment_id] = {"target_id": target_elem_id} Session().flush() c.co = comment c.at_version_num = None c.is_new = True rendered_comment = render( - 'rhodecode:templates/changeset/changeset_comment_block.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/changeset/changeset_comment_block.mako", + self._get_template_context(c), + self.request, + ) data[comment_id].update(comment.get_dict()) - data[comment_id].update({'rendered_text': rendered_comment}) + data[comment_id].update({"rendered_text": rendered_comment}) Session().commit() # skip channelstream for draft comments if not all_drafts: - comment_broadcast_channel = channelstream.comment_channel( - self.db_repo_name, pull_request_obj=pull_request) + comment_broadcast_channel = channelstream.comment_channel(self.db_repo_name, pull_request_obj=pull_request) comment_data = data - posted_comment_type = 'inline' if is_inline else 'general' + posted_comment_type = "inline" if is_inline else "general" if len(data) == 1: - msg = _('posted {} new {} comment').format(len(data), posted_comment_type) + msg = _("posted {} new {} comment").format(len(data), posted_comment_type) else: - msg = _('posted {} new {} comments').format(len(data), posted_comment_type) + msg = _("posted {} new {} comments").format(len(data), posted_comment_type) channelstream.comment_channelstream_push( - self.request, comment_broadcast_channel, self._rhodecode_user, msg, - comment_data=comment_data) + self.request, comment_broadcast_channel, self._rhodecode_user, msg, comment_data=comment_data + ) return data @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def pull_request_comment_create(self): _ = self.request.translate - pull_request = PullRequest.get_or_404(self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) if pull_request.is_closed(): - log.debug('comment: forbidden because pull request is closed') + log.debug("comment: forbidden because pull request is closed") raise HTTPForbidden() - allowed_to_comment = PullRequestModel().check_user_comment( - pull_request, self._rhodecode_user) + allowed_to_comment = PullRequestModel().check_user_comment(pull_request, self._rhodecode_user) if not allowed_to_comment: - log.debug('comment: forbidden because pull request is from forbidden repo') + log.debug("comment: forbidden because pull request is from forbidden repo") raise HTTPForbidden() comment_data = { - 'comment_type': self.request.POST.get('comment_type'), - 'text': self.request.POST.get('text'), - 'status': self.request.POST.get('changeset_status', None), - 'is_draft': self.request.POST.get('draft'), - 'resolves_comment_id': self.request.POST.get('resolves_comment_id', None), - 'close_pull_request': self.request.POST.get('close_pull_request'), - 'f_path': self.request.POST.get('f_path'), - 'line': self.request.POST.get('line'), + "comment_type": self.request.POST.get("comment_type"), + "text": self.request.POST.get("text"), + "status": self.request.POST.get("changeset_status", None), + "is_draft": self.request.POST.get("draft"), + "resolves_comment_id": self.request.POST.get("resolves_comment_id", None), + "close_pull_request": self.request.POST.get("close_pull_request"), + "f_path": self.request.POST.get("f_path"), + "line": self.request.POST.get("line"), } data = self._pull_request_comments_create(pull_request, [comment_data]) @@ -1734,15 +1722,12 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def pull_request_comment_delete(self): - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id']) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) - comment = ChangesetComment.get_or_404( - self.request.matchdict['comment_id']) + comment = ChangesetComment.get_or_404(self.request.matchdict["comment_id"]) comment_id = comment.comment_id if comment.immutable: @@ -1750,11 +1735,11 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): raise HTTPForbidden() if pull_request.is_closed(): - log.debug('comment: forbidden because pull request is closed') + log.debug("comment: forbidden because pull request is closed") raise HTTPForbidden() if not comment: - log.debug('Comment with id:%s not found, skipping', comment_id) + log.debug("Comment with id:%s not found, skipping", comment_id) # comment already deleted in another call probably return True @@ -1762,8 +1747,8 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): # don't allow deleting comments on closed pull request raise HTTPForbidden() - is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name) - super_admin = h.HasPermissionAny('hg.admin')() + is_repo_admin = h.HasRepoPermissionAny("repository.admin")(self.db_repo_name) + super_admin = h.HasPermissionAny("hg.admin")() comment_owner = comment.author.user_id == self._rhodecode_user.user_id is_repo_comment = comment.repo.repo_name == self.db_repo_name comment_repo_admin = is_repo_admin and is_repo_comment @@ -1779,28 +1764,25 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): calculated_status = comment.pull_request.calculated_review_status() if old_calculated_status != calculated_status: PullRequestModel().trigger_pull_request_hook( - comment.pull_request, self._rhodecode_user, 'review_status_change', - data={'status': calculated_status}) + comment.pull_request, + self._rhodecode_user, + "review_status_change", + data={"status": calculated_status}, + ) return True else: - log.warning('No permissions for user %s to delete comment_id: %s', - self._rhodecode_db_user, comment_id) + log.warning("No permissions for user %s to delete comment_id: %s", self._rhodecode_db_user, comment_id) raise HTTPNotFound() @LoginRequired() @NotAnonymous() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") @CSRFRequired() def pull_request_comment_edit(self): self.load_default_context() - pull_request = PullRequest.get_or_404( - self.request.matchdict['pull_request_id'] - ) - comment = ChangesetComment.get_or_404( - self.request.matchdict['comment_id'] - ) + pull_request = PullRequest.get_or_404(self.request.matchdict["pull_request_id"]) + comment = ChangesetComment.get_or_404(self.request.matchdict["comment_id"]) comment_id = comment.comment_id if comment.immutable: @@ -1808,27 +1790,25 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): raise HTTPForbidden() if pull_request.is_closed(): - log.debug('comment: forbidden because pull request is closed') + log.debug("comment: forbidden because pull request is closed") raise HTTPForbidden() if comment.pull_request.is_closed(): # don't allow deleting comments on closed pull request raise HTTPForbidden() - is_repo_admin = h.HasRepoPermissionAny('repository.admin')(self.db_repo_name) - super_admin = h.HasPermissionAny('hg.admin')() + is_repo_admin = h.HasRepoPermissionAny("repository.admin")(self.db_repo_name) + super_admin = h.HasPermissionAny("hg.admin")() comment_owner = comment.author.user_id == self._rhodecode_user.user_id is_repo_comment = comment.repo.repo_name == self.db_repo_name comment_repo_admin = is_repo_admin and is_repo_comment if super_admin or comment_owner or comment_repo_admin: - text = self.request.POST.get('text') - version = self.request.POST.get('version') + text = self.request.POST.get("text") + version = self.request.POST.get("version") if text == comment.text: log.warning( - 'Comment(PR): ' - 'Trying to create new version ' - 'with the same comment body {}'.format( + "Comment(PR): Trying to create new version with the same comment body {}".format( comment_id, ) ) @@ -1838,8 +1818,7 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): version = int(version) else: log.warning( - 'Comment(PR): Wrong version type {} {} ' - 'for comment {}'.format( + "Comment(PR): Wrong version type {} {} for comment {}".format( version, type(version), comment_id, @@ -1863,19 +1842,17 @@ class RepoPullRequestsView(RepoAppView, DataGridAppView): Session().commit() if not comment.draft: PullRequestModel().trigger_pull_request_hook( - pull_request, self._rhodecode_user, 'comment_edit', - data={'comment': comment}) + pull_request, self._rhodecode_user, "comment_edit", data={"comment": comment} + ) return { - 'comment_history_id': comment_history.comment_history_id, - 'comment_id': comment.comment_id, - 'comment_version': comment_history.version, - 'comment_author_username': comment_history.author.username, - 'comment_author_gravatar': h.gravatar_url(comment_history.author.email, 16, request=self.request), - 'comment_created_on': h.age_component(comment_history.created_on, - time_is_local=True), + "comment_history_id": comment_history.comment_history_id, + "comment_id": comment.comment_id, + "comment_version": comment_history.version, + "comment_author_username": comment_history.author.username, + "comment_author_gravatar": h.gravatar_url(comment_history.author.email, 16, request=self.request), + "comment_created_on": h.age_component(comment_history.created_on, time_is_local=True), } else: - log.warning('No permissions for user %s to edit comment_id: %s', - self._rhodecode_db_user, comment_id) + log.warning("No permissions for user %s to edit comment_id: %s", self._rhodecode_db_user, comment_id) raise HTTPNotFound() diff --git a/rhodecode/apps/repository/views/repo_review_rules.py b/rhodecode/apps/repository/views/repo_review_rules.py index 385c17c3..b33f082a 100644 --- a/rhodecode/apps/repository/views/repo_review_rules.py +++ b/rhodecode/apps/repository/views/repo_review_rules.py @@ -19,7 +19,6 @@ import logging - from rhodecode.apps._base import RepoAppView from rhodecode.apps.repository.utils import get_default_reviewers_data from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator @@ -35,34 +34,33 @@ class RepoReviewRulesView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_review_rules(self): c = self.load_default_context() - c.active = 'reviewers' + c.active = "reviewers" return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_default_reviewers_data(self): self.load_default_context() request = self.request source_repo = self.db_repo source_repo_name = source_repo.repo_name - target_repo_name = request.GET.get('target_repo', source_repo_name) + target_repo_name = request.GET.get("target_repo", source_repo_name) target_repo = Repository.get_by_repo_name(target_repo_name) current_user = request.user.get_instance() - source_commit_id = request.GET['source_ref'] - source_type = request.GET['source_ref_type'] - source_name = request.GET['source_ref_name'] + source_commit_id = request.GET["source_ref"] + source_type = request.GET["source_ref_type"] + source_name = request.GET["source_ref_name"] - target_commit_id = request.GET['target_ref'] - target_type = request.GET['target_ref_type'] - target_name = request.GET['target_ref_name'] + target_commit_id = request.GET["target_ref"] + target_type = request.GET["target_ref_type"] + target_name = request.GET["target_ref_name"] try: review_data = get_default_reviewers_data( @@ -70,12 +68,12 @@ class RepoReviewRulesView(RepoAppView): source_repo, Reference(source_type, source_name, source_commit_id), target_repo, - Reference(target_type, target_name, target_commit_id) + Reference(target_type, target_name, target_commit_id), ) except ValueError: # No common ancestor msg = "No Common ancestor found between target and source reference" log.exception(msg) - return {'diff_info': {'error': msg}} + return {"diff_info": {"error": msg}} return review_data diff --git a/rhodecode/apps/repository/views/repo_settings.py b/rhodecode/apps/repository/views/repo_settings.py index 3109c8b1..9aaa651b 100644 --- a/rhodecode/apps/repository/views/repo_settings.py +++ b/rhodecode/apps/repository/views/repo_settings.py @@ -26,8 +26,7 @@ from rhodecode.apps._base import RepoAppView from rhodecode.forms import RcForm from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.model.db import RepositoryField, RepoGroup, Repository, User from rhodecode.model.meta import Session from rhodecode.model.permission import PermissionModel @@ -39,13 +38,10 @@ log = logging.getLogger(__name__) class RepoSettingsView(RepoAppView): - def load_default_context(self): c = self._get_local_tmpl_context() - acl_groups = RepoGroupList( - RepoGroup.query().all(), - perm_set=['group.write', 'group.admin']) + acl_groups = RepoGroupList(RepoGroup.query().all(), perm_set=["group.write", "group.admin"]) c.repo_groups = RepoGroup.groups_choices(groups=acl_groups) c.repo_groups_choices = list(map(lambda k: k[0], c.repo_groups)) @@ -60,16 +56,14 @@ class RepoSettingsView(RepoAppView): if c.repository_requirements_missing or self.rhodecode_vcs_repo is None: # we might be in missing requirement state, so we load things # without touching scm_instance() - c.landing_revs_choices, c.landing_revs = \ - ScmModel().get_repo_landing_revs(self.request.translate) + c.landing_revs_choices, c.landing_revs = ScmModel().get_repo_landing_revs(self.request.translate) else: - c.landing_revs_choices, c.landing_revs = \ - ScmModel().get_repo_landing_revs( - self.request.translate, self.db_repo) + c.landing_revs_choices, c.landing_revs = ScmModel().get_repo_landing_revs( + self.request.translate, self.db_repo + ) c.personal_repo_group = c.auth_user.personal_repo_group - c.repo_fields = RepositoryField.query()\ - .filter(RepositoryField.repository == self.db_repo).all() + c.repo_fields = RepositoryField.query().filter(RepositoryField.repository == self.db_repo).all() return c def _get_schema(self, c, old_values=None): @@ -82,30 +76,30 @@ class RepoSettingsView(RepoAppView): repo_repo_group_items=c.repo_groups, # user caller user=self._rhodecode_user, - old_values=old_values + old_values=old_values, ) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def edit_settings(self): c = self.load_default_context() - c.active = 'settings' + c.active = "settings" defaults = RepoModel()._get_defaults(self.db_repo_name) - defaults['repo_owner'] = defaults['user'] - defaults['repo_landing_commit_ref'] = defaults['repo_landing_rev'] + defaults["repo_owner"] = defaults["user"] + defaults["repo_landing_commit_ref"] = defaults["repo_landing_rev"] schema = self._get_schema(c) c.form = RcForm(schema, appstruct=defaults) return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_settings_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'settings' + c.active = "settings" old_repo_name = self.db_repo_name old_values = self.db_repo.get_api_data() @@ -113,7 +107,7 @@ class RepoSettingsView(RepoAppView): c.form = RcForm(schema) pstruct = list(self.request.POST.items()) - pstruct.append(('repo_type', self.db_repo.repo_type)) + pstruct.append(("repo_type", self.db_repo.repo_type)) try: schema_data = c.form.validate(pstruct) except deform.ValidationFailure as err_form: @@ -122,28 +116,27 @@ class RepoSettingsView(RepoAppView): # data is now VALID, proceed with updates # save validated data back into the updates dict validated_updates = dict( - repo_name=schema_data['repo_group']['repo_name_without_group'], - repo_group=schema_data['repo_group']['repo_group_id'], - - user=schema_data['repo_owner'], - repo_description=schema_data['repo_description'], - repo_private=schema_data['repo_private'], - clone_uri=schema_data['repo_clone_uri'], - push_uri=schema_data['repo_push_uri'], - repo_landing_rev=schema_data['repo_landing_commit_ref'], - repo_enable_statistics=schema_data['repo_enable_statistics'], - repo_enable_locking=schema_data['repo_enable_locking'], - repo_enable_downloads=schema_data['repo_enable_downloads'], + repo_name=schema_data["repo_group"]["repo_name_without_group"], + repo_group=schema_data["repo_group"]["repo_group_id"], + user=schema_data["repo_owner"], + repo_description=schema_data["repo_description"], + repo_private=schema_data["repo_private"], + clone_uri=schema_data["repo_clone_uri"], + push_uri=schema_data["repo_push_uri"], + repo_landing_rev=schema_data["repo_landing_commit_ref"], + repo_enable_statistics=schema_data["repo_enable_statistics"], + repo_enable_locking=schema_data["repo_enable_locking"], + repo_enable_downloads=schema_data["repo_enable_downloads"], ) # detect if SYNC URI changed, if we get OLD means we keep old values - if schema_data['repo_clone_uri_change'] == 'OLD': - validated_updates['clone_uri'] = self.db_repo.clone_uri + if schema_data["repo_clone_uri_change"] == "OLD": + validated_updates["clone_uri"] = self.db_repo.clone_uri - if schema_data['repo_push_uri_change'] == 'OLD': - validated_updates['push_uri'] = self.db_repo.push_uri + if schema_data["repo_push_uri_change"] == "OLD": + validated_updates["push_uri"] = self.db_repo.push_uri # use the new full name for redirect - new_repo_name = schema_data['repo_group']['repo_name_with_group'] + new_repo_name = schema_data["repo_group"]["repo_name_with_group"] # save extra fields into our validated data for key, value in pstruct: @@ -155,34 +148,31 @@ class RepoSettingsView(RepoAppView): ScmModel().mark_for_invalidation(new_repo_name) audit_logger.store_web( - 'repo.edit', action_data={'old_data': old_values}, - user=self._rhodecode_user, repo=self.db_repo) + "repo.edit", action_data={"old_data": old_values}, user=self._rhodecode_user, repo=self.db_repo + ) Session().commit() - h.flash(_('Repository `{}` updated successfully').format(old_repo_name), - category='success') + h.flash(_("Repository `{}` updated successfully").format(old_repo_name), category="success") except Exception: log.exception("Exception during update of repository") - h.flash(_('Error occurred during update of repository {}').format( - old_repo_name), category='error') + h.flash(_("Error occurred during update of repository {}").format(old_repo_name), category="error") name_changed = old_repo_name != new_repo_name if name_changed: current_perms = self.db_repo.permissions(expand_from_user_groups=True) - affected_user_ids = [perm['user_id'] for perm in current_perms] + affected_user_ids = [perm["user_id"] for perm in current_perms] # NOTE(marcink): also add owner maybe it has changed - owner = User.get_by_username(schema_data['repo_owner']) + owner = User.get_by_username(schema_data["repo_owner"]) owner_id = owner.user_id if owner else self._rhodecode_user.user_id affected_user_ids.extend([self._rhodecode_user.user_id, owner_id]) PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound( - h.route_path('edit_repo', repo_name=new_repo_name)) + raise HTTPFound(h.route_path("edit_repo", repo_name=new_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.write", "repository.admin") def toggle_locking(self): """ Toggle locking of repository by simple GET call to url @@ -194,24 +184,19 @@ class RepoSettingsView(RepoAppView): if repo.enable_locking: if repo.locked[0]: Repository.unlock(repo) - action = _('Unlocked') + action = _("Unlocked") else: - Repository.lock( - repo, self._rhodecode_user.user_id, - lock_reason=Repository.LOCK_WEB) - action = _('Locked') + Repository.lock(repo, self._rhodecode_user.user_id, lock_reason=Repository.LOCK_WEB) + action = _("Locked") - h.flash(_('Repository has been %s') % action, - category='success') + h.flash(_("Repository has been %s") % action, category="success") except Exception: log.exception("Exception during unlocking") - h.flash(_('An error occurred during unlocking'), - category='error') - raise HTTPFound( - h.route_path('repo_summary', repo_name=self.db_repo_name)) + h.flash(_("An error occurred during unlocking"), category="error") + raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def edit_statistics_form(self): c = self.load_default_context() @@ -221,19 +206,18 @@ class RepoSettingsView(RepoAppView): else: last_rev = 0 - c.active = 'statistics' + c.active = "statistics" c.stats_revision = last_rev c.repo_last_rev = self.rhodecode_vcs_repo.count() if last_rev == 0 or c.repo_last_rev == 0: c.stats_percentage = 0 else: - c.stats_percentage = '%.2f' % ( - (float(last_rev) / c.repo_last_rev) * 100) + c.stats_percentage = "%.2f" % ((float(last_rev) / c.repo_last_rev) * 100) return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_statistics_reset(self): _ = self.request.translate @@ -242,34 +226,27 @@ class RepoSettingsView(RepoAppView): RepoModel().delete_stats(self.db_repo_name) Session().commit() except Exception: - log.exception('Edit statistics failure') - h.flash(_('An error occurred during deletion of repository stats'), - category='error') - raise HTTPFound( - h.route_path('edit_repo_statistics', repo_name=self.db_repo_name)) + log.exception("Edit statistics failure") + h.flash(_("An error occurred during deletion of repository stats"), category="error") + raise HTTPFound(h.route_path("edit_repo_statistics", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_settings_quick_actions(self): _ = self.request.translate - set_lock = self.request.GET.get('set_lock') - set_unlock = self.request.GET.get('set_unlock') + set_lock = self.request.GET.get("set_lock") + set_unlock = self.request.GET.get("set_unlock") try: if set_lock: - Repository.lock(self.db_repo, self._rhodecode_user.user_id, - lock_reason=Repository.LOCK_WEB) - h.flash(_('Locked repository'), category='success') + Repository.lock(self.db_repo, self._rhodecode_user.user_id, lock_reason=Repository.LOCK_WEB) + h.flash(_("Locked repository"), category="success") elif set_unlock: Repository.unlock(self.db_repo) - h.flash(_('Unlocked repository'), category='success') + h.flash(_("Unlocked repository"), category="success") except Exception as e: log.exception("Exception during unlocking") - h.flash(_('An error occurred during unlocking'), category='error') - - raise HTTPFound( - h.route_path('repo_summary', repo_name=self.db_repo_name)) - - + h.flash(_("An error occurred during unlocking"), category="error") + raise HTTPFound(h.route_path("repo_summary", repo_name=self.db_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_settings_advanced.py b/rhodecode/apps/repository/views/repo_settings_advanced.py index 8519e742..87a0c098 100644 --- a/rhodecode/apps/repository/views/repo_settings_advanced.py +++ b/rhodecode/apps/repository/views/repo_settings_advanced.py @@ -26,9 +26,7 @@ from rhodecode import events from rhodecode.apps._base import RepoAppView from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired, - HasRepoPermissionAny) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired, HasRepoPermissionAny from rhodecode.lib.exceptions import AttachedForksError, AttachedPullRequestsError, AttachedArtifactsError from rhodecode.lib.utils2 import safe_int from rhodecode.lib.vcs import RepositoryError @@ -41,7 +39,6 @@ log = logging.getLogger(__name__) class RepoSettingsAdvancedView(RepoAppView): - def load_default_context(self): c = self._get_local_tmpl_context() return c @@ -54,35 +51,38 @@ class RepoSettingsAdvancedView(RepoAppView): return user_permissions @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def edit_advanced(self): _ = self.request.translate c = self.load_default_context() - c.active = 'advanced' + c.active = "advanced" c.default_user_id = User.get_default_user_id() - c.in_public_journal = UserFollowing.query() \ - .filter(UserFollowing.user_id == c.default_user_id) \ - .filter(UserFollowing.follows_repository == self.db_repo).scalar() + c.in_public_journal = ( + UserFollowing.query() + .filter(UserFollowing.user_id == c.default_user_id) + .filter(UserFollowing.follows_repository == self.db_repo) + .scalar() + ) c.ver_info_dict = self.rhodecode_vcs_repo.get_hooks_info() c.hooks_outdated = False try: - if Version(c.ver_info_dict['pre_version']) < Version(c.rhodecode_version): + if Version(c.ver_info_dict["pre_version"]) < Version(c.rhodecode_version): c.hooks_outdated = True except Exception: pass # update commit cache if GET flag is present - if self.request.GET.get('update_commit_cache'): + if self.request.GET.get("update_commit_cache"): self.db_repo.update_commit_cache() - h.flash(_('updated commit cache'), category='success') + h.flash(_("updated commit cache"), category="success") return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_advanced_archive(self): """ @@ -98,31 +98,26 @@ class RepoSettingsAdvancedView(RepoAppView): repo = audit_logger.RepoWrap(repo_id=None, repo_name=self.db_repo.repo_name) audit_logger.store_web( - 'repo.archive', action_data={'old_data': old_data}, - user=self._rhodecode_user, repo=repo) + "repo.archive", action_data={"old_data": old_data}, user=self._rhodecode_user, repo=repo + ) ScmModel().mark_for_invalidation(self.db_repo_name, delete=True) - h.flash( - _('Archived repository `%s`') % self.db_repo_name, - category='success') + h.flash(_("Archived repository `%s`") % self.db_repo_name, category="success") Session().commit() except Exception: log.exception("Exception during archiving of repository") - h.flash(_('An error occurred during archiving of `%s`') - % self.db_repo_name, category='error') + h.flash(_("An error occurred during archiving of `%s`") % self.db_repo_name, category="error") # redirect to advanced for more deletion options - raise HTTPFound( - h.route_path('edit_repo_advanced', repo_name=self.db_repo_name, - _anchor='advanced-archive')) + raise HTTPFound(h.route_path("edit_repo_advanced", repo_name=self.db_repo_name, _anchor="advanced-archive")) # flush permissions for all users defined in permissions affected_user_ids = self._get_users_with_permissions().keys() PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound(h.route_path('home')) + raise HTTPFound(h.route_path("home")) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_advanced_delete(self): """ @@ -130,80 +125,79 @@ class RepoSettingsAdvancedView(RepoAppView): because of attached forks or other errors. """ _ = self.request.translate - handle_forks = self.request.POST.get('forks', None) - if handle_forks == 'detach_forks': - handle_forks = 'detach' - elif handle_forks == 'delete_forks': - handle_forks = 'delete' + handle_forks = self.request.POST.get("forks", None) + if handle_forks == "detach_forks": + handle_forks = "detach" + elif handle_forks == "delete_forks": + handle_forks = "delete" - repo_advanced_url = h.route_path( - 'edit_repo_advanced', repo_name=self.db_repo_name, - _anchor='advanced-delete') + repo_advanced_url = h.route_path("edit_repo_advanced", repo_name=self.db_repo_name, _anchor="advanced-delete") try: old_data = self.db_repo.get_api_data() RepoModel().delete(self.db_repo, forks=handle_forks) _forks = self.db_repo.forks.count() if _forks and handle_forks: - if handle_forks == 'detach_forks': - h.flash(_('Detached %s forks') % _forks, category='success') - elif handle_forks == 'delete_forks': - h.flash(_('Deleted %s forks') % _forks, category='success') + if handle_forks == "detach_forks": + h.flash(_("Detached %s forks") % _forks, category="success") + elif handle_forks == "delete_forks": + h.flash(_("Deleted %s forks") % _forks, category="success") repo = audit_logger.RepoWrap(repo_id=None, repo_name=self.db_repo.repo_name) audit_logger.store_web( - 'repo.delete', action_data={'old_data': old_data}, - user=self._rhodecode_user, repo=repo) + "repo.delete", action_data={"old_data": old_data}, user=self._rhodecode_user, repo=repo + ) ScmModel().mark_for_invalidation(self.db_repo_name, delete=True) - h.flash( - _('Deleted repository `%s`') % self.db_repo_name, - category='success') + h.flash(_("Deleted repository `%s`") % self.db_repo_name, category="success") Session().commit() except AttachedForksError: - delete_anchor = h.link_to(_('detach or delete'), repo_advanced_url) - h.flash(_('Cannot delete `{repo}` it still contains attached forks. ' - 'Try using {delete_or_detach} option.') - .format(repo=self.db_repo_name, delete_or_detach=delete_anchor), - category='warning') + delete_anchor = h.link_to(_("detach or delete"), repo_advanced_url) + h.flash( + _( + "Cannot delete `{repo}` it still contains attached forks. Try using {delete_or_detach} option." + ).format(repo=self.db_repo_name, delete_or_detach=delete_anchor), + category="warning", + ) # redirect to advanced for forks handle action ? raise HTTPFound(repo_advanced_url) except AttachedPullRequestsError: - attached_prs = len(self.db_repo.pull_requests_source + - self.db_repo.pull_requests_target) + attached_prs = len(self.db_repo.pull_requests_source + self.db_repo.pull_requests_target) h.flash( - _('Cannot delete `{repo}` it still contains {num} attached pull requests. ' - 'Consider archiving the repository instead.').format( - repo=self.db_repo_name, num=attached_prs), category='warning') + _( + "Cannot delete `{repo}` it still contains {num} attached pull requests. " + "Consider archiving the repository instead." + ).format(repo=self.db_repo_name, num=attached_prs), + category="warning", + ) # redirect to advanced for forks handle action ? raise HTTPFound(repo_advanced_url) except AttachedArtifactsError: - attached_artifacts = len(self.db_repo.artifacts) h.flash( - _('Cannot delete `{repo}` it still contains {num} attached artifacts. ' - 'Consider archiving the repository instead.').format( - repo=self.db_repo_name, num=attached_artifacts), category='warning') + _( + "Cannot delete `{repo}` it still contains {num} attached artifacts. " + "Consider archiving the repository instead." + ).format(repo=self.db_repo_name, num=attached_artifacts), + category="warning", + ) # redirect to advanced for forks handle action ? raise HTTPFound(repo_advanced_url) except Exception: log.exception("Exception during deletion of repository") - h.flash(_('An error occurred during deletion of `%s`') - % self.db_repo_name, category='error') + h.flash(_("An error occurred during deletion of `%s`") % self.db_repo_name, category="error") # redirect to advanced for more deletion options - raise HTTPFound( - h.route_path('edit_repo_advanced', repo_name=self.db_repo_name, - _anchor='advanced-delete')) + raise HTTPFound(h.route_path("edit_repo_advanced", repo_name=self.db_repo_name, _anchor="advanced-delete")) - raise HTTPFound(h.route_path('home')) + raise HTTPFound(h.route_path("home")) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_advanced_journal(self): """ @@ -215,19 +209,15 @@ class RepoSettingsAdvancedView(RepoAppView): try: user_id = User.get_default_user_id() ScmModel().toggle_following_repo(self.db_repo.repo_id, user_id) - h.flash(_('Updated repository visibility in public journal'), - category='success') + h.flash(_("Updated repository visibility in public journal"), category="success") Session().commit() except Exception: - h.flash(_('An error occurred during setting this ' - 'repository in public journal'), - category='error') + h.flash(_("An error occurred during setting this repository in public journal"), category="error") - raise HTTPFound( - h.route_path('edit_repo_advanced', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("edit_repo_advanced", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_advanced_fork(self): """ @@ -235,14 +225,13 @@ class RepoSettingsAdvancedView(RepoAppView): """ _ = self.request.translate - new_fork_id = safe_int(self.request.POST.get('id_fork_of')) + new_fork_id = safe_int(self.request.POST.get("id_fork_of")) # valid repo, re-check permissions if new_fork_id: repo = Repository.get(new_fork_id) # ensure we have at least read access to the repo we mark - perm_check = HasRepoPermissionAny( - 'repository.read', 'repository.write', 'repository.admin') + perm_check = HasRepoPermissionAny("repository.read", "repository.write", "repository.admin") if repo and perm_check(repo_name=repo.repo_name): new_fork_id = repo.repo_id @@ -250,52 +239,45 @@ class RepoSettingsAdvancedView(RepoAppView): new_fork_id = None try: - repo = ScmModel().mark_as_fork( - self.db_repo_name, new_fork_id, self._rhodecode_user.user_id) - fork = repo.fork.repo_name if repo.fork else _('Nothing') + repo = ScmModel().mark_as_fork(self.db_repo_name, new_fork_id, self._rhodecode_user.user_id) + fork = repo.fork.repo_name if repo.fork else _("Nothing") Session().commit() - h.flash( - _('Marked repo %s as fork of %s') % (self.db_repo_name, fork), - category='success') + h.flash(_("Marked repo %s as fork of %s") % (self.db_repo_name, fork), category="success") except RepositoryError as e: log.exception("Repository Error occurred") - h.flash(str(e), category='error') + h.flash(str(e), category="error") except Exception: log.exception("Exception while editing fork") - h.flash(_('An error occurred during this operation'), - category='error') + h.flash(_("An error occurred during this operation"), category="error") - raise HTTPFound( - h.route_path('edit_repo_advanced', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("edit_repo_advanced", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def edit_advanced_toggle_locking(self): """ Toggle locking of repository """ _ = self.request.translate - set_lock = self.request.POST.get('set_lock') - set_unlock = self.request.POST.get('set_unlock') + set_lock = self.request.POST.get("set_lock") + set_unlock = self.request.POST.get("set_unlock") try: if set_lock: - Repository.lock(self.db_repo, self._rhodecode_user.user_id, - lock_reason=Repository.LOCK_WEB) - h.flash(_('Locked repository'), category='success') + Repository.lock(self.db_repo, self._rhodecode_user.user_id, lock_reason=Repository.LOCK_WEB) + h.flash(_("Locked repository"), category="success") elif set_unlock: Repository.unlock(self.db_repo) - h.flash(_('Unlocked repository'), category='success') + h.flash(_("Unlocked repository"), category="success") except Exception as e: log.exception("Exception during unlocking") - h.flash(_('An error occurred during unlocking'), category='error') + h.flash(_("An error occurred during unlocking"), category="error") - raise HTTPFound( - h.route_path('edit_repo_advanced', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("edit_repo_advanced", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def edit_advanced_install_hooks(self): """ Install Hooks for repository @@ -303,7 +285,5 @@ class RepoSettingsAdvancedView(RepoAppView): _ = self.request.translate self.load_default_context() self.rhodecode_vcs_repo.install_hooks(force=True) - h.flash(_('installed updated hooks into this repository'), - category='success') - raise HTTPFound( - h.route_path('edit_repo_advanced', repo_name=self.db_repo_name)) + h.flash(_("installed updated hooks into this repository"), category="success") + raise HTTPFound(h.route_path("edit_repo_advanced", repo_name=self.db_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_settings_fields.py b/rhodecode/apps/repository/views/repo_settings_fields.py index e7ae7ec3..56cb42c2 100644 --- a/rhodecode/apps/repository/views/repo_settings_fields.py +++ b/rhodecode/apps/repository/views/repo_settings_fields.py @@ -26,8 +26,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import RepoAppView from rhodecode.lib import audit_logger from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.model.db import RepositoryField from rhodecode.model.forms import RepoFieldForm from rhodecode.model.meta import Session @@ -40,22 +39,20 @@ class RepoSettingsFieldsView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_field_edit(self): c = self.load_default_context() - c.active = 'fields' - c.repo_fields = RepositoryField.query() \ - .filter(RepositoryField.repository == self.db_repo).all() + c.active = "fields" + c.repo_fields = RepositoryField.query().filter(RepositoryField.repository == self.db_repo).all() return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_field_create(self): _ = self.request.translate @@ -65,36 +62,35 @@ class RepoSettingsFieldsView(RepoAppView): form_result = form.to_python(dict(self.request.POST)) RepoModel().add_repo_field( self.db_repo_name, - form_result['new_field_key'], - field_type=form_result['new_field_type'], - field_value=form_result['new_field_value'], - field_label=form_result['new_field_label'], - field_desc=form_result['new_field_desc']) + form_result["new_field_key"], + field_type=form_result["new_field_type"], + field_value=form_result["new_field_value"], + field_label=form_result["new_field_label"], + field_desc=form_result["new_field_desc"], + ) Session().commit() except Exception as e: log.exception("Exception creating field") - msg = _('An error occurred during creation of field') + msg = _("An error occurred during creation of field") if isinstance(e, formencode.Invalid): msg += ". " + e.msg - h.flash(msg, category='error') + h.flash(msg, category="error") - raise HTTPFound( - h.route_path('edit_repo_fields', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("edit_repo_fields", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_field_delete(self): _ = self.request.translate - field = RepositoryField.get_or_404(self.request.matchdict['field_id']) + field = RepositoryField.get_or_404(self.request.matchdict["field_id"]) try: RepoModel().delete_repo_field(self.db_repo_name, field.field_key) Session().commit() except Exception: - log.exception('Exception during removal of field') - msg = _('An error occurred during removal of field') - h.flash(msg, category='error') + log.exception("Exception during removal of field") + msg = _("An error occurred during removal of field") + h.flash(msg, category="error") - raise HTTPFound( - h.route_path('edit_repo_fields', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("edit_repo_fields", repo_name=self.db_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_settings_issue_trackers.py b/rhodecode/apps/repository/views/repo_settings_issue_trackers.py index 545da8c4..827e7a45 100644 --- a/rhodecode/apps/repository/views/repo_settings_issue_trackers.py +++ b/rhodecode/apps/repository/views/repo_settings_issue_trackers.py @@ -25,8 +25,7 @@ import formencode from rhodecode.apps._base import RepoAppView from rhodecode.lib import audit_logger from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.model.forms import IssueTrackerPatternsForm from rhodecode.model.meta import Session from rhodecode.model.settings import SettingsModel @@ -40,11 +39,11 @@ class RepoSettingsIssueTrackersView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_issuetracker(self): c = self.load_default_context() - c.active = 'issuetracker' - c.data = 'data' + c.active = "issuetracker" + c.data = "data" c.settings_model = self.db_repo_patterns c.global_patterns = c.settings_model.get_global_settings() @@ -53,71 +52,61 @@ class RepoSettingsIssueTrackersView(RepoAppView): return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_issuetracker_test(self): - return h.urlify_commit_message( - self.request.POST.get('test_text', ''), - self.db_repo_name) + return h.urlify_commit_message(self.request.POST.get("test_text", ""), self.db_repo_name) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_issuetracker_delete(self): _ = self.request.translate - uid = self.request.POST.get('uid') + uid = self.request.POST.get("uid") repo_settings = self.db_repo_patterns try: repo_settings.delete_entries(uid) except Exception: - h.flash(_('Error occurred during deleting issue tracker entry'), - category='error') + h.flash(_("Error occurred during deleting issue tracker entry"), category="error") raise HTTPNotFound() SettingsModel().invalidate_settings_cache() - h.flash(_('Removed issue tracker entry.'), category='success') + h.flash(_("Removed issue tracker entry."), category="success") - return {'deleted': uid} + return {"deleted": uid} def _update_patterns(self, form, repo_settings): - for uid in form['delete_patterns']: + for uid in form["delete_patterns"]: repo_settings.delete_entries(uid) - for pattern_data in form['patterns']: + for pattern_data in form["patterns"]: for setting_key, pattern, type_ in pattern_data: - sett = repo_settings.create_or_update_setting( - setting_key, pattern.strip(), type_) + sett = repo_settings.create_or_update_setting(setting_key, pattern.strip(), type_) Session().add(sett) Session().commit() @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_issuetracker_update(self): _ = self.request.translate # Save inheritance repo_settings = self.db_repo_patterns - inherited = ( - self.request.POST.get('inherit_global_issuetracker') == "inherited") + inherited = self.request.POST.get("inherit_global_issuetracker") == "inherited" repo_settings.inherit_global_settings = inherited Session().commit() try: form = IssueTrackerPatternsForm(self.request.translate)().to_python(self.request.POST) except formencode.Invalid as errors: - log.exception('Failed to add new pattern') + log.exception("Failed to add new pattern") error = errors - h.flash(_(f'Invalid issue tracker pattern: {error}'), - category='error') - raise HTTPFound( - h.route_path('edit_repo_issuetracker', - repo_name=self.db_repo_name)) + h.flash(_(f"Invalid issue tracker pattern: {error}"), category="error") + raise HTTPFound(h.route_path("edit_repo_issuetracker", repo_name=self.db_repo_name)) if form: self._update_patterns(form, repo_settings) - h.flash(_('Updated issue tracker entries'), category='success') - raise HTTPFound( - h.route_path('edit_repo_issuetracker', repo_name=self.db_repo_name)) - + h.flash(_("Updated issue tracker entries"), category="success") + raise HTTPFound(h.route_path("edit_repo_issuetracker", repo_name=self.db_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_settings_remote.py b/rhodecode/apps/repository/views/repo_settings_remote.py index 82cb5ed0..56908dca 100644 --- a/rhodecode/apps/repository/views/repo_settings_remote.py +++ b/rhodecode/apps/repository/views/repo_settings_remote.py @@ -23,8 +23,7 @@ from pyramid.httpexceptions import HTTPFound from rhodecode.apps._base import RepoAppView from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, CSRFRequired, HasRepoPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, CSRFRequired, HasRepoPermissionAnyDecorator from rhodecode.model.scm import ScmModel log = logging.getLogger(__name__) @@ -36,27 +35,24 @@ class RepoSettingsRemoteView(RepoAppView): return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_remote_edit_form(self): c = self.load_default_context() - c.active = 'remote' + c.active = "remote" return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_remote_pull_changes(self): _ = self.request.translate self.load_default_context() try: - ScmModel().pull_changes( - self.db_repo_name, self._rhodecode_user.username, sync_large_objects=True) - h.flash(_('Pulled from remote location'), category='success') + ScmModel().pull_changes(self.db_repo_name, self._rhodecode_user.username, sync_large_objects=True) + h.flash(_("Pulled from remote location"), category="success") except Exception: log.exception("Exception during pull from remote") - h.flash(_('An error occurred during pull from remote location'), - category='error') - raise HTTPFound( - h.route_path('edit_repo_remote', repo_name=self.db_repo_name)) + h.flash(_("An error occurred during pull from remote location"), category="error") + raise HTTPFound(h.route_path("edit_repo_remote", repo_name=self.db_repo_name)) diff --git a/rhodecode/apps/repository/views/repo_settings_vcs.py b/rhodecode/apps/repository/views/repo_settings_vcs.py index 1e96798f..a2c2f289 100644 --- a/rhodecode/apps/repository/views/repo_settings_vcs.py +++ b/rhodecode/apps/repository/views/repo_settings_vcs.py @@ -28,8 +28,7 @@ import rhodecode from rhodecode.apps._base import RepoAppView from rhodecode.apps.svn_support import config_keys from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.model.forms import RepoVcsSettingsForm from rhodecode.model.meta import Session from rhodecode.model.settings import VcsSettingsModel, SettingNotFound @@ -50,28 +49,26 @@ class RepoSettingsVcsView(RepoAppView): repo_defaults.update(global_defaults) repo_defaults.update(model.get_repo_settings()) - global_defaults = { - f'{k}_inherited': global_defaults[k] - for k in global_defaults} + global_defaults = {f"{k}_inherited": global_defaults[k] for k in global_defaults} - defaults = { - 'inherit_global_settings': model.inherit_global_settings - } + defaults = {"inherit_global_settings": model.inherit_global_settings} defaults.update(global_defaults) defaults.update(repo_defaults) - defaults.update({ - 'new_svn_branch': '', - 'new_svn_tag': '', - }) + defaults.update( + { + "new_svn_branch": "", + "new_svn_tag": "", + } + ) return defaults @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def repo_vcs_settings(self): c = self.load_default_context() model = VcsSettingsModel(repo=self.db_repo_name) - c.active = 'vcs' + c.active = "vcs" c.global_svn_branch_patterns = model.get_global_svn_branch_patterns() c.global_svn_tag_patterns = model.get_global_svn_tag_patterns() c.svn_branch_patterns = model.get_repo_svn_branch_patterns() @@ -81,25 +78,19 @@ class RepoSettingsVcsView(RepoAppView): c.svn_config_path = rhodecode.ConfigGet().get_str(config_keys.config_file_path) defaults = self._vcs_form_defaults(self.db_repo_name) - c.inherit_global_settings = defaults['inherit_global_settings'] + c.inherit_global_settings = defaults["inherit_global_settings"] - data = render('rhodecode:templates/admin/repos/repo_edit.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False - ) + data = render("rhodecode:templates/admin/repos/repo_edit.mako", self._get_template_context(c), self.request) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_settings_vcs_update(self): _ = self.request.translate c = self.load_default_context() - c.active = 'vcs' + c.active = "vcs" model = VcsSettingsModel(repo=self.db_repo_name) c.global_svn_branch_patterns = model.get_global_svn_branch_patterns() @@ -110,52 +101,42 @@ class RepoSettingsVcsView(RepoAppView): c.svn_config_path = rhodecode.ConfigGet().get_str(config_keys.config_file_path) defaults = self._vcs_form_defaults(self.db_repo_name) - c.inherit_global_settings = defaults['inherit_global_settings'] + c.inherit_global_settings = defaults["inherit_global_settings"] application_form = RepoVcsSettingsForm(self.request.translate, self.db_repo_name)() try: form_result = application_form.to_python(dict(self.request.POST)) except formencode.Invalid as errors: - h.flash(_("Some form inputs contain invalid data."), - category='error') + h.flash(_("Some form inputs contain invalid data."), category="error") - data = render('rhodecode:templates/admin/repos/repo_edit.mako', - self._get_template_context(c), self.request) + data = render("rhodecode:templates/admin/repos/repo_edit.mako", self._get_template_context(c), self.request) html = formencode.htmlfill.render( - data, - defaults=errors.value, - errors=errors.error_dict or {}, - encoding="UTF-8", - force_defaults=False + data, defaults=errors.value, errors=errors.error_dict or {}, encoding="UTF-8", force_defaults=False ) return Response(html) try: - inherit_global_settings = form_result['inherit_global_settings'] - model.create_or_update_repo_settings( - form_result, inherit_global_settings=inherit_global_settings) + inherit_global_settings = form_result["inherit_global_settings"] + model.create_or_update_repo_settings(form_result, inherit_global_settings=inherit_global_settings) Session().commit() - h.flash(_('Updated VCS settings'), category='success') + h.flash(_("Updated VCS settings"), category="success") except Exception: log.exception("Exception while updating settings") - h.flash( - _('Error occurred during updating repository VCS settings'), - category='error') + h.flash(_("Error occurred during updating repository VCS settings"), category="error") - raise HTTPFound( - h.route_path('edit_repo_vcs', repo_name=self.db_repo_name)) + raise HTTPFound(h.route_path("edit_repo_vcs", repo_name=self.db_repo_name)) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def repo_settings_delete_svn_pattern(self): self.load_default_context() - delete_pattern_id = self.request.POST.get('delete_svn_pattern') + delete_pattern_id = self.request.POST.get("delete_svn_pattern") model = VcsSettingsModel(repo=self.db_repo_name) try: model.delete_repo_svn_pattern(delete_pattern_id) except SettingNotFound: - log.exception('Failed to delete SVN pattern') + log.exception("Failed to delete SVN pattern") raise HTTPBadRequest() Session().commit() diff --git a/rhodecode/apps/repository/views/repo_strip.py b/rhodecode/apps/repository/views/repo_strip.py index 9e02cf48..94ac7020 100644 --- a/rhodecode/apps/repository/views/repo_strip.py +++ b/rhodecode/apps/repository/views/repo_strip.py @@ -22,8 +22,7 @@ import logging from rhodecode.apps._base import RepoAppView from rhodecode.lib import audit_logger from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired from rhodecode.lib.ext_json import json log = logging.getLogger(__name__) @@ -33,45 +32,48 @@ class RepoStripView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def strip(self): c = self.load_default_context() - c.active = 'strip' + c.active = "strip" c.strip_limit = 10 return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def strip_check(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + data = {} rp = self.request.POST for i in range(1, 11): - changeset_id_key = f'changeset_id-{i}' - changeset_id_branch_key = f'changeset_id_branch-{i}' + changeset_id_key = f"changeset_id-{i}" + changeset_id_branch_key = f"changeset_id_branch-{i}" check = rp.get(changeset_id_key) if check: data[i] = self.db_repo.get_commit(rp[changeset_id_key]) if isinstance(data[i], EmptyCommit): - data[i] = {'rev': None, 'commit': h.escape(rp[changeset_id_key])} + data[i] = {"rev": None, "commit": h.escape(rp[changeset_id_key])} else: rp_branch = rp.get(changeset_id_branch_key) - data[i] = {'rev': data[i].raw_id, 'branch': data[i].branch or rp_branch, - 'author': h.escape(data[i].author), - 'comment': h.escape(data[i].message)} + data[i] = { + "rev": data[i].raw_id, + "branch": data[i].branch or rp_branch, + "author": h.escape(data[i].author), + "comment": h.escape(data[i].message), + } else: break return data @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def strip_execute(self): from rhodecode.model.scm import ScmModel @@ -84,22 +86,28 @@ class RepoStripView(RepoAppView): for idx in rp: commit = json.loads(rp[idx]) # If someone put two times the same branch - if commit['branch'] in data.keys(): + if commit["branch"] in data.keys(): continue try: - ScmModel().strip( - repo=self.db_repo, - commit_id=commit['rev'], branch=commit['branch']) - log.info('Stripped commit %s from repo `%s` by %s', - commit['rev'], self.db_repo_name, user) - data[commit['rev']] = True + ScmModel().strip(repo=self.db_repo, commit_id=commit["rev"], branch=commit["branch"]) + log.info("Stripped commit %s from repo `%s` by %s", commit["rev"], self.db_repo_name, user) + data[commit["rev"]] = True audit_logger.store_web( - 'repo.commit.strip', action_data={'commit_id': commit['rev']}, - repo=self.db_repo, user=self._rhodecode_user, commit=True) + "repo.commit.strip", + action_data={"commit_id": commit["rev"]}, + repo=self.db_repo, + user=self._rhodecode_user, + commit=True, + ) except Exception as e: - data[commit['rev']] = False - log.debug('Stripped commit %s from repo `%s` failed by %s, exeption %s', - commit['rev'], self.db_repo_name, user, e) + data[commit["rev"]] = False + log.debug( + "Stripped commit %s from repo `%s` failed by %s, exeption %s", + commit["rev"], + self.db_repo_name, + user, + e, + ) return data diff --git a/rhodecode/apps/repository/views/repo_summary.py b/rhodecode/apps/repository/views/repo_summary.py index 25565485..92f8fe2e 100644 --- a/rhodecode/apps/repository/views/repo_summary.py +++ b/rhodecode/apps/repository/views/repo_summary.py @@ -23,17 +23,15 @@ import time import rhodecode - from rhodecode.lib.view_utils import get_format_ref_id from rhodecode.apps._base import RepoAppView -from rhodecode.config.conf import (LANGUAGES_EXTENSIONS_MAP) +from rhodecode.config.conf import LANGUAGES_EXTENSIONS_MAP from rhodecode.lib import helpers as h, rc_cache from rhodecode.lib.utils2 import safe_str, safe_int from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.lib.ext_json import json from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.vcs.exceptions import ( - CommitError, EmptyRepositoryError, CommitDoesNotExistError) +from rhodecode.lib.vcs.exceptions import CommitError, EmptyRepositoryError, CommitDoesNotExistError from rhodecode.model.db import Statistics, CacheKey, User from rhodecode.model.meta import Session from rhodecode.model.scm import ScmModel @@ -42,7 +40,6 @@ log = logging.getLogger(__name__) class RepoSummaryView(RepoAppView): - def load_default_context(self): c = self._get_local_tmpl_context(include_app_defaults=True) c.rhodecode_repo = None @@ -51,35 +48,27 @@ class RepoSummaryView(RepoAppView): return c def _load_commits_context(self, c): - p = safe_int(self.request.GET.get('page'), 1) - size = safe_int(self.request.GET.get('size'), 10) + p = safe_int(self.request.GET.get("page"), 1) + size = safe_int(self.request.GET.get("size"), 10) def url_generator(page_num): - query_params = { - 'page': page_num, - 'size': size - } - return h.route_path( - 'repo_summary_commits', - repo_name=c.rhodecode_db_repo.repo_name, _query=query_params) + query_params = {"page": page_num, "size": size} + return h.route_path("repo_summary_commits", repo_name=c.rhodecode_db_repo.repo_name, _query=query_params) pre_load = self.get_commit_preload_attrs() try: - collection = self.rhodecode_vcs_repo.get_commits( - pre_load=pre_load, translate_tags=False) + collection = self.rhodecode_vcs_repo.get_commits(pre_load=pre_load, translate_tags=False) except EmptyRepositoryError: collection = self.rhodecode_vcs_repo - c.repo_commits = h.RepoPage( - collection, page=p, items_per_page=size, url_maker=url_generator) + c.repo_commits = h.RepoPage(collection, page=p, items_per_page=size, url_maker=url_generator) page_ids = [x.raw_id for x in c.repo_commits] c.comments = self.db_repo.get_comments(page_ids) c.statuses = self.db_repo.statuses(page_ids) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def summary_commits(self): c = self.load_default_context() self._prepare_and_set_clone_url(c) @@ -87,8 +76,7 @@ class RepoSummaryView(RepoAppView): return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def summary(self): c = self.load_default_context() @@ -98,9 +86,7 @@ class RepoSummaryView(RepoAppView): # If enabled, get statistics data c.show_stats = bool(self.db_repo.enable_statistics) - stats = Session().query(Statistics) \ - .filter(Statistics.repository == self.db_repo) \ - .scalar() + stats = Session().query(Statistics).filter(Statistics.repository == self.db_repo).scalar() c.stats_percentage = 0 @@ -110,11 +96,8 @@ class RepoSummaryView(RepoAppView): # Sort first by decreasing count and second by the file extension, # so we have a consistent output. - lang_stats_items = sorted(lang_stats_d.items(), - key=lambda k: (-k[1], k[0]))[:10] - lang_stats = [(x, {"count": y, - "desc": LANGUAGES_EXTENSIONS_MAP.get(x)}) - for x, y in lang_stats_items] + lang_stats_items = sorted(lang_stats_d.items(), key=lambda k: (-k[1], k[0]))[:10] + lang_stats = [(x, {"count": y, "desc": LANGUAGES_EXTENSIONS_MAP.get(x)}) for x, y in lang_stats_items] c.trending_languages = json.dumps(lang_stats) else: @@ -128,12 +111,10 @@ class RepoSummaryView(RepoAppView): # first interaction with the VCS instance after here... if c.repository_requirements_missing: - self.request.override_renderer = \ - 'rhodecode:templates/summary/missing_requirements.mako' + self.request.override_renderer = "rhodecode:templates/summary/missing_requirements.mako" return self._get_template_context(c) - c.readme_data, c.readme_file = \ - self._get_readme_data(self.db_repo, c.visual.default_renderer) + c.readme_data, c.readme_file = self._get_readme_data(self.db_repo, c.visual.default_renderer) # loads the summary commits template context self._load_commits_context(c) @@ -141,29 +122,27 @@ class RepoSummaryView(RepoAppView): return self._get_template_context(c) @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_stats(self): show_stats = bool(self.db_repo.enable_statistics) repo_id = self.db_repo.repo_id landing_commit = self.db_repo.get_landing_commit() if isinstance(landing_commit, EmptyCommit): - return {'size': 0, 'code_stats': {}} + return {"size": 0, "code_stats": {}} - cache_seconds = safe_int(rhodecode.CONFIG.get('rc_cache.cache_repo.expiration_time')) + cache_seconds = safe_int(rhodecode.CONFIG.get("rc_cache.cache_repo.expiration_time")) cache_on = cache_seconds > 0 log.debug( - 'Computing REPO STATS for repo_id %s commit_id `%s` ' - 'with caching: %s[TTL: %ss]' % ( - repo_id, landing_commit, cache_on, cache_seconds or 0)) + "Computing REPO STATS for repo_id %s commit_id `%s` " + "with caching: %s[TTL: %ss]" % (repo_id, landing_commit, cache_on, cache_seconds or 0) + ) - cache_namespace_uid = f'repo.{repo_id}' - region = rc_cache.get_or_create_region('cache_repo', cache_namespace_uid) + cache_namespace_uid = f"repo.{repo_id}" + region = rc_cache.get_or_create_region("cache_repo", cache_namespace_uid) - @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, - condition=cache_on) + @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, condition=cache_on) def compute_stats(repo_id, commit_id, _show_stats): code_stats = {} size = 0 @@ -178,40 +157,34 @@ class RepoSummaryView(RepoAppView): ext_info = LANGUAGES_EXTENSIONS_MAP.get(ext) if ext_info: if ext in code_stats: - code_stats[ext]['count'] += 1 + code_stats[ext]["count"] += 1 else: code_stats[ext] = {"count": 1, "desc": ext_info} except (EmptyRepositoryError, CommitDoesNotExistError): pass - return {'size': h.format_byte_size_binary(size), - 'code_stats': code_stats} + return {"size": h.format_byte_size_binary(size), "code_stats": code_stats} stats = compute_stats(self.db_repo.repo_id, landing_commit.raw_id, show_stats) return stats @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_refs_data(self): _ = self.request.translate self.load_default_context() repo = self.rhodecode_vcs_repo refs_to_create = [ - (_("Branch"), repo.branches, 'branch'), - (_("Tag"), repo.tags, 'tag'), - (_("Bookmark"), repo.bookmarks, 'book'), + (_("Branch"), repo.branches, "branch"), + (_("Tag"), repo.tags, "tag"), + (_("Bookmark"), repo.bookmarks, "book"), ] res = self._create_reference_data(repo, self.db_repo_name, refs_to_create) - data = { - 'more': False, - 'results': res - } + data = {"more": False, "results": res} return data @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def repo_refs_changelog_data(self): _ = self.request.translate self.load_default_context() @@ -219,17 +192,13 @@ class RepoSummaryView(RepoAppView): repo = self.rhodecode_vcs_repo refs_to_create = [ - (_("Branches"), repo.branches, 'branch'), - (_("Closed branches"), repo.branches_closed, 'branch_closed'), + (_("Branches"), repo.branches, "branch"), + (_("Closed branches"), repo.branches_closed, "branch_closed"), # TODO: enable when vcs can handle bookmarks filters # (_("Bookmarks"), repo.bookmarks, "book"), ] - res = self._create_reference_data( - repo, self.db_repo_name, refs_to_create) - data = { - 'more': False, - 'results': res - } + res = self._create_reference_data(repo, self.db_repo_name, refs_to_create) + data = {"more": False, "results": res} return data def _create_reference_data(self, repo, full_repo_name, refs_to_create): @@ -238,35 +207,37 @@ class RepoSummaryView(RepoAppView): result = [] for title, refs, ref_type in refs_to_create: if refs: - result.append({ - 'text': title, - 'children': self._create_reference_items( - repo, full_repo_name, refs, ref_type, - format_ref_id), - }) + result.append( + { + "text": title, + "children": self._create_reference_items(repo, full_repo_name, refs, ref_type, format_ref_id), + } + ) return result def _create_reference_items(self, repo, full_repo_name, refs, ref_type, format_ref_id): result = [] is_svn = h.is_svn(repo) for ref_name, raw_id in refs.items(): - files_url = self._create_files_url( - repo, full_repo_name, ref_name, raw_id, is_svn) - result.append({ - 'text': ref_name, - 'id': format_ref_id(ref_name, raw_id), - 'raw_id': raw_id, - 'type': ref_type, - 'files_url': files_url, - 'idx': 0, - }) + files_url = self._create_files_url(repo, full_repo_name, ref_name, raw_id, is_svn) + result.append( + { + "text": ref_name, + "id": format_ref_id(ref_name, raw_id), + "raw_id": raw_id, + "type": ref_type, + "files_url": files_url, + "idx": 0, + } + ) return result def _create_files_url(self, repo, full_repo_name, ref_name, raw_id, is_svn): - use_commit_id = '/' in ref_name or is_svn + use_commit_id = "/" in ref_name or is_svn return h.route_path( - 'repo_files', + "repo_files", repo_name=full_repo_name, - f_path=ref_name if is_svn else '', + f_path=ref_name if is_svn else "", commit_id=raw_id if use_commit_id else ref_name, - _query=dict(at=ref_name)) + _query=dict(at=ref_name), + ) diff --git a/rhodecode/apps/repository/views/repo_tags.py b/rhodecode/apps/repository/views/repo_tags.py index 4ce393d5..2c876cff 100644 --- a/rhodecode/apps/repository/views/repo_tags.py +++ b/rhodecode/apps/repository/views/repo_tags.py @@ -20,17 +20,15 @@ import logging from rhodecode.apps._base import BaseReferencesView from rhodecode.lib import ext_json -from rhodecode.lib.auth import (LoginRequired, HasRepoPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator from rhodecode.model.scm import ScmModel log = logging.getLogger(__name__) class RepoTagsView(BaseReferencesView): - @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def tags(self): c = self.load_default_context() self._prepare_and_set_clone_url(c) @@ -38,8 +36,7 @@ class RepoTagsView(BaseReferencesView): c.repository_forks = ScmModel().get_forks(self.db_repo) ref_items = self.rhodecode_vcs_repo.tags.items() - data = self.load_refs_context( - ref_items=ref_items, partials_template='tags/tags_data.mako') + data = self.load_refs_context(ref_items=ref_items, partials_template="tags/tags_data.mako") c.has_references = bool(data) c.data = ext_json.str_json(data) diff --git a/rhodecode/apps/search/__init__.py b/rhodecode/apps/search/__init__.py index a1d27e59..9c715681 100644 --- a/rhodecode/apps/search/__init__.py +++ b/rhodecode/apps/search/__init__.py @@ -19,42 +19,40 @@ from rhodecode.apps._base import ADMIN_PREFIX def includeme(config): - from rhodecode.apps.search.views import ( - SearchView, SearchRepoView, SearchRepoGroupView) + from rhodecode.apps.search.views import SearchView, SearchRepoView, SearchRepoGroupView - config.add_route( - name='search', - pattern=ADMIN_PREFIX + '/search') + config.add_route(name="search", pattern=ADMIN_PREFIX + "/search") config.add_view( SearchView, - attr='search', - route_name='search', request_method='GET', - renderer='rhodecode:templates/search/search.mako') + attr="search", + route_name="search", + request_method="GET", + renderer="rhodecode:templates/search/search.mako", + ) - config.add_route( - name='search_repo', - pattern='/{repo_name:.*?[^/]}/_search', repo_route=True) + config.add_route(name="search_repo", pattern="/{repo_name:.*?[^/]}/_search", repo_route=True) config.add_view( SearchRepoView, - attr='search_repo', - route_name='search_repo', request_method='GET', - renderer='rhodecode:templates/search/search.mako') + attr="search_repo", + route_name="search_repo", + request_method="GET", + renderer="rhodecode:templates/search/search.mako", + ) - config.add_route( - name='search_repo_alt', - pattern='/{repo_name:.*?[^/]}/search', repo_route=True) + config.add_route(name="search_repo_alt", pattern="/{repo_name:.*?[^/]}/search", repo_route=True) config.add_view( SearchRepoView, - attr='search_repo', - route_name='search_repo_alt', request_method='GET', - renderer='rhodecode:templates/search/search.mako') + attr="search_repo", + route_name="search_repo_alt", + request_method="GET", + renderer="rhodecode:templates/search/search.mako", + ) - config.add_route( - name='search_repo_group', - pattern='/{repo_group_name:.*?[^/]}/_search', - repo_group_route=True) + config.add_route(name="search_repo_group", pattern="/{repo_group_name:.*?[^/]}/_search", repo_group_route=True) config.add_view( SearchRepoGroupView, - attr='search_repo_group', - route_name='search_repo_group', request_method='GET', - renderer='rhodecode:templates/search/search.mako') + attr="search_repo_group", + route_name="search_repo_group", + request_method="GET", + renderer="rhodecode:templates/search/search.mako", + ) diff --git a/rhodecode/apps/search/tests/test_search.py b/rhodecode/apps/search/tests/test_search.py index eaf6a4df..bc8ac7ae 100644 --- a/rhodecode/apps/search/tests/test_search.py +++ b/rhodecode/apps/search/tests/test_search.py @@ -22,176 +22,177 @@ import mock import pytest from whoosh import query -from rhodecode.tests import ( - TestController, HG_REPO, - TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) +from rhodecode.tests import TestController, HG_REPO, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS from rhodecode.tests.routes import route_path class TestSearchController(TestController): - def test_index(self): self.log_user() - response = self.app.get(route_path('search')) + response = self.app.get(route_path("search")) assert_response = response.assert_response() - assert_response.one_element_exists('input#q') + assert_response.one_element_exists("input#q") def test_search_files_empty_search(self): if os.path.isdir(self.index_location): - pytest.skip('skipped due to existing index') + pytest.skip("skipped due to existing index") else: self.log_user() - response = self.app.get(route_path('search'), - {'q': HG_REPO}) - response.mustcontain('There is no index to search in. ' - 'Please run whoosh indexer') + response = self.app.get(route_path("search"), {"q": HG_REPO}) + response.mustcontain("There is no index to search in. Please run whoosh indexer") def test_search_validation(self): self.log_user() - response = self.app.get(route_path('search'), - {'q': query, 'type': 'content', 'page_limit': 1000}) + response = self.app.get(route_path("search"), {"q": query, "type": "content", "page_limit": 1000}) - response.mustcontain( - 'page_limit - 1000 is greater than maximum value 500') + response.mustcontain("page_limit - 1000 is greater than maximum value 500") - @pytest.mark.parametrize("query, expected_hits, expected_paths", [ - ('todo', 23, [ - 'vcs/backends/hg/inmemory.py', - 'vcs/tests/test_git.py']), - ('extension:rst installation', 6, [ - 'docs/index.rst', - 'docs/installation.rst']), - ('def repo', 87, [ - 'vcs/tests/test_git.py', - 'vcs/tests/test_changesets.py']), - ('repository:%s def test' % HG_REPO, 18, [ - 'vcs/tests/test_git.py', - 'vcs/tests/test_changesets.py']), - ('"def main"', 9, [ - 'vcs/__init__.py', - 'vcs/tests/__init__.py', - 'vcs/utils/progressbar.py']), - ('owner:test_admin', 358, [ - 'vcs/tests/base.py', - 'MANIFEST.in', - 'vcs/utils/termcolors.py', - 'docs/theme/ADC/static/documentation.png']), - ('owner:test_admin def main', 72, [ - 'vcs/__init__.py', - 'vcs/tests/test_utils_filesize.py', - 'vcs/tests/test_cli.py']), - ('owner:michał test', 0, []), - ]) + @pytest.mark.parametrize( + "query, expected_hits, expected_paths", + [ + ("todo", 23, ["vcs/backends/hg/inmemory.py", "vcs/tests/test_git.py"]), + ("extension:rst installation", 6, ["docs/index.rst", "docs/installation.rst"]), + ("def repo", 87, ["vcs/tests/test_git.py", "vcs/tests/test_changesets.py"]), + ("repository:%s def test" % HG_REPO, 18, ["vcs/tests/test_git.py", "vcs/tests/test_changesets.py"]), + ('"def main"', 9, ["vcs/__init__.py", "vcs/tests/__init__.py", "vcs/utils/progressbar.py"]), + ( + "owner:test_admin", + 358, + [ + "vcs/tests/base.py", + "MANIFEST.in", + "vcs/utils/termcolors.py", + "docs/theme/ADC/static/documentation.png", + ], + ), + ( + "owner:test_admin def main", + 72, + ["vcs/__init__.py", "vcs/tests/test_utils_filesize.py", "vcs/tests/test_cli.py"], + ), + ("owner:michał test", 0, []), + ], + ) def test_search_files(self, query, expected_hits, expected_paths): self.log_user() - response = self.app.get(route_path('search'), - {'q': query, 'type': 'content', 'page_limit': 500}) + response = self.app.get(route_path("search"), {"q": query, "type": "content", "page_limit": 500}) - response.mustcontain('%s results' % expected_hits) + response.mustcontain("%s results" % expected_hits) for path in expected_paths: response.mustcontain(path) - @pytest.mark.parametrize("query, expected_hits, expected_commits", [ - ('bother to ask where to fetch repo during tests', 3, [ - ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1'), - ('git', 'c6eb379775c578a95dad8ddab53f963b80894850'), - ('svn', '98')]), - ('michał', 0, []), - ('changed:tests/utils.py', 36, [ - ('hg', 'a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1')]), - ('changed:vcs/utils/archivers.py', 11, [ - ('hg', '25213a5fbb048dff8ba65d21e466a835536e5b70'), - ('hg', '47aedd538bf616eedcb0e7d630ea476df0e159c7'), - ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'), - ('hg', '04ad456aefd6461aea24f90b63954b6b1ce07b3e'), - ('git', 'c994f0de03b2a0aa848a04fc2c0d7e737dba31fc'), - ('git', 'd1f898326327e20524fe22417c22d71064fe54a1'), - ('git', 'fe568b4081755c12abf6ba673ba777fc02a415f3'), - ('git', 'bafe786f0d8c2ff7da5c1dcfcfa577de0b5e92f1')]), - ('added:README.rst', 3, [ - ('hg', '3803844fdbd3b711175fc3da9bdacfcd6d29a6fb'), - ('git', 'ff7ca51e58c505fec0dd2491de52c622bb7a806b'), - ('svn', '8')]), - ('changed:lazy.py', 15, [ - ('hg', 'eaa291c5e6ae6126a203059de9854ccf7b5baa12'), - ('git', '17438a11f72b93f56d0e08e7d1fa79a378578a82'), - ('svn', '82'), - ('svn', '262'), - ('hg', 'f5d23247fad4856a1dabd5838afade1e0eed24fb'), - ('git', '33fa3223355104431402a888fa77a4e9956feb3e') - ]), - ('author:marcin@python-blog.com ' - 'commit_id:b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [ - ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]), - ('b986218ba1c9b0d6a259fac9b050b1724ed8e545', 1, [ - ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]), - ('b986218b', 1, [ - ('hg', 'b986218ba1c9b0d6a259fac9b050b1724ed8e545')]), - ]) - def test_search_commit_messages( - self, query, expected_hits, expected_commits, enabled_backends): + @pytest.mark.parametrize( + "query, expected_hits, expected_commits", + [ + ( + "bother to ask where to fetch repo during tests", + 3, + [ + ("hg", "a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1"), + ("git", "c6eb379775c578a95dad8ddab53f963b80894850"), + ("svn", "98"), + ], + ), + ("michał", 0, []), + ("changed:tests/utils.py", 36, [("hg", "a00c1b6f5d7a6ae678fd553a8b81d92367f7ecf1")]), + ( + "changed:vcs/utils/archivers.py", + 11, + [ + ("hg", "25213a5fbb048dff8ba65d21e466a835536e5b70"), + ("hg", "47aedd538bf616eedcb0e7d630ea476df0e159c7"), + ("hg", "f5d23247fad4856a1dabd5838afade1e0eed24fb"), + ("hg", "04ad456aefd6461aea24f90b63954b6b1ce07b3e"), + ("git", "c994f0de03b2a0aa848a04fc2c0d7e737dba31fc"), + ("git", "d1f898326327e20524fe22417c22d71064fe54a1"), + ("git", "fe568b4081755c12abf6ba673ba777fc02a415f3"), + ("git", "bafe786f0d8c2ff7da5c1dcfcfa577de0b5e92f1"), + ], + ), + ( + "added:README.rst", + 3, + [ + ("hg", "3803844fdbd3b711175fc3da9bdacfcd6d29a6fb"), + ("git", "ff7ca51e58c505fec0dd2491de52c622bb7a806b"), + ("svn", "8"), + ], + ), + ( + "changed:lazy.py", + 15, + [ + ("hg", "eaa291c5e6ae6126a203059de9854ccf7b5baa12"), + ("git", "17438a11f72b93f56d0e08e7d1fa79a378578a82"), + ("svn", "82"), + ("svn", "262"), + ("hg", "f5d23247fad4856a1dabd5838afade1e0eed24fb"), + ("git", "33fa3223355104431402a888fa77a4e9956feb3e"), + ], + ), + ( + "author:marcin@python-blog.com commit_id:b986218ba1c9b0d6a259fac9b050b1724ed8e545", + 1, + [("hg", "b986218ba1c9b0d6a259fac9b050b1724ed8e545")], + ), + ("b986218ba1c9b0d6a259fac9b050b1724ed8e545", 1, [("hg", "b986218ba1c9b0d6a259fac9b050b1724ed8e545")]), + ("b986218b", 1, [("hg", "b986218ba1c9b0d6a259fac9b050b1724ed8e545")]), + ], + ) + def test_search_commit_messages(self, query, expected_hits, expected_commits, enabled_backends): self.log_user() - response = self.app.get(route_path('search'), - {'q': query, 'type': 'commit', 'page_limit': 500}) + response = self.app.get(route_path("search"), {"q": query, "type": "commit", "page_limit": 500}) - response.mustcontain('%s results' % expected_hits) + response.mustcontain("%s results" % expected_hits) for backend, commit_id in expected_commits: if backend in enabled_backends: response.mustcontain(commit_id) - @pytest.mark.parametrize("query, expected_hits, expected_paths", [ - ('readme.rst', 3, []), - ('test*', 75, []), - ('*model*', 1, []), - ('extension:rst', 48, []), - ('extension:rst api', 24, []), - ]) + @pytest.mark.parametrize( + "query, expected_hits, expected_paths", + [ + ("readme.rst", 3, []), + ("test*", 75, []), + ("*model*", 1, []), + ("extension:rst", 48, []), + ("extension:rst api", 24, []), + ], + ) def test_search_file_paths(self, query, expected_hits, expected_paths): self.log_user() - response = self.app.get(route_path('search'), - {'q': query, 'type': 'path', 'page_limit': 500}) + response = self.app.get(route_path("search"), {"q": query, "type": "path", "page_limit": 500}) - response.mustcontain('%s results' % expected_hits) + response.mustcontain("%s results" % expected_hits) for path in expected_paths: response.mustcontain(path) def test_search_commit_message_specific_repo(self, backend): self.log_user() response = self.app.get( - route_path('search_repo',repo_name=backend.repo_name), - {'q': 'bother to ask where to fetch repo during tests', - 'type': 'commit'}) + route_path("search_repo", repo_name=backend.repo_name), + {"q": "bother to ask where to fetch repo during tests", "type": "commit"}, + ) - response.mustcontain('1 results') + response.mustcontain("1 results") def test_filters_are_not_applied_for_admin_user(self): self.log_user() - with mock.patch('whoosh.searching.Searcher.search') as search_mock: - search_mock.return_value = mock.MagicMock( - scored_length=lambda: 100, - runtime=10 - ) - self.app.get(route_path('search'), - {'q': 'test query', 'type': 'commit'}) + with mock.patch("whoosh.searching.Searcher.search") as search_mock: + search_mock.return_value = mock.MagicMock(scored_length=lambda: 100, runtime=10) + self.app.get(route_path("search"), {"q": "test query", "type": "commit"}) assert search_mock.call_count == 1 _, kwargs = search_mock.call_args - assert kwargs['filter'] is None + assert kwargs["filter"] is None def test_filters_are_applied_for_normal_user(self, enabled_backends): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - with mock.patch('whoosh.searching.Searcher.search') as search_mock: - search_mock.return_value = mock.MagicMock( - scored_length=lambda: 100, - runtime=10 - ) - self.app.get(route_path('search'), - {'q': 'test query', 'type': 'commit'}) + with mock.patch("whoosh.searching.Searcher.search") as search_mock: + search_mock.return_value = mock.MagicMock(scored_length=lambda: 100, runtime=10) + self.app.get(route_path("search"), {"q": "test query", "type": "commit"}) assert search_mock.call_count == 1 _, kwargs = search_mock.call_args - assert isinstance(kwargs['filter'], query.Or) - expected_repositories = [ - f'vcs_test_{b}' for b in enabled_backends] - queried_repositories = [ - name for type_, name in kwargs['filter'].all_terms()] + assert isinstance(kwargs["filter"], query.Or) + expected_repositories = [f"vcs_test_{b}" for b in enabled_backends] + queried_repositories = [name for type_, name in kwargs["filter"].all_terms()] for repository in expected_repositories: assert repository in queried_repositories diff --git a/rhodecode/apps/search/views.py b/rhodecode/apps/search/views.py index 664bf3ba..3bccfe51 100644 --- a/rhodecode/apps/search/views.py +++ b/rhodecode/apps/search/views.py @@ -24,8 +24,7 @@ import urllib.error from webhelpers2.html.tools import update_params from rhodecode.apps._base import BaseAppView, RepoAppView, RepoGroupAppView -from rhodecode.lib.auth import ( - LoginRequired, HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator) +from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator from rhodecode.lib.helpers import Page from rhodecode.lib.utils2 import safe_str from rhodecode.lib.index import searcher_from_config @@ -38,7 +37,7 @@ log = logging.getLogger(__name__) def perform_search(request, tmpl_context, repo_name=None, repo_group_name=None): searcher = searcher_from_config(request.registry.settings) formatted_results = [] - execution_time = '' + execution_time = "" schema = search_schema.SearchParamsSchema() search_tags = [] @@ -48,60 +47,66 @@ def perform_search(request, tmpl_context, repo_name=None, repo_group_name=None): try: search_params = schema.deserialize( dict( - search_query=request.GET.get('q'), - search_type=request.GET.get('type'), - search_sort=request.GET.get('sort'), - search_max_lines=request.GET.get('max_lines'), - page_limit=request.GET.get('page_limit'), - requested_page=request.GET.get('page'), - ) + search_query=request.GET.get("q"), + search_type=request.GET.get("type"), + search_sort=request.GET.get("sort"), + search_max_lines=request.GET.get("max_lines"), + page_limit=request.GET.get("page_limit"), + requested_page=request.GET.get("page"), + ) ) except validation_schema.Invalid as e: errors = e.children def url_generator(page_num): - query_params = { - 'page': page_num, - 'q': safe_str(search_query), - 'type': safe_str(search_type), - 'max_lines': search_max_lines, - 'sort': search_sort + "page": page_num, + "q": safe_str(search_query), + "type": safe_str(search_type), + "max_lines": search_max_lines, + "sort": search_sort, } - return '?' + urllib.parse.urlencode(query_params) + return "?" + urllib.parse.urlencode(query_params) c = tmpl_context - search_query = search_params.get('search_query') - search_type = search_params.get('search_type') - search_sort = search_params.get('search_sort') - search_max_lines = search_params.get('search_max_lines') - if search_params.get('search_query'): - page_limit = search_params['page_limit'] - requested_page = search_params['requested_page'] + search_query = search_params.get("search_query") + search_type = search_params.get("search_type") + search_sort = search_params.get("search_sort") + search_max_lines = search_params.get("search_max_lines") + if search_params.get("search_query"): + page_limit = search_params["page_limit"] + requested_page = search_params["requested_page"] try: search_result = searcher.search( - search_query, search_type, c.auth_user, repo_name, repo_group_name, - requested_page=requested_page, page_limit=page_limit, sort=search_sort) + search_query, + search_type, + c.auth_user, + repo_name, + repo_group_name, + requested_page=requested_page, + page_limit=page_limit, + sort=search_sort, + ) formatted_results = Page( - search_result['results'], page=requested_page, - item_count=search_result['count'], - items_per_page=page_limit, url_maker=url_generator) + search_result["results"], + page=requested_page, + item_count=search_result["count"], + items_per_page=page_limit, + url_maker=url_generator, + ) finally: searcher.cleanup() search_tags = searcher.extract_search_tags(search_query) - if not search_result['error']: - execution_time = '{} results ({:.4f} seconds)'.format( - search_result['count'], - search_result['runtime']) + if not search_result["error"]: + execution_time = "{} results ({:.4f} seconds)".format(search_result["count"], search_result["runtime"]) elif not errors: - node = schema['search_query'] - errors = [ - validation_schema.Invalid(node, search_result['error'])] + node = schema["search_query"] + errors = [validation_schema.Invalid(node, search_result["error"])] c.perm_user = c.auth_user c.repo_name = repo_name @@ -116,11 +121,11 @@ def perform_search(request, tmpl_context, repo_name=None, repo_group_name=None): direction, sort_field = searcher.get_sort(search_type, search_sort) sort_definition = searcher.sort_def(search_type, direction, sort_field) - c.sort = '' + c.sort = "" c.sort_tag = None c.sort_tag_dir = direction if sort_definition: - c.sort = f'{direction}:{sort_field}' + c.sort = f"{direction}:{sort_field}" c.sort_tag = sort_field @@ -139,12 +144,11 @@ class SearchView(BaseAppView): class SearchRepoView(RepoAppView): def load_default_context(self): c = self._get_local_tmpl_context() - c.active = 'search' + c.active = "search" return c @LoginRequired() - @HasRepoPermissionAnyDecorator( - 'repository.read', 'repository.write', 'repository.admin') + @HasRepoPermissionAnyDecorator("repository.read", "repository.write", "repository.admin") def search_repo(self): c = self.load_default_context() perform_search(self.request, c, repo_name=self.db_repo_name) @@ -154,12 +158,11 @@ class SearchRepoView(RepoAppView): class SearchRepoGroupView(RepoGroupAppView): def load_default_context(self): c = self._get_local_tmpl_context() - c.active = 'search' + c.active = "search" return c @LoginRequired() - @HasRepoGroupPermissionAnyDecorator( - 'group.read', 'group.write', 'group.admin') + @HasRepoGroupPermissionAnyDecorator("group.read", "group.write", "group.admin") def search_repo_group(self): c = self.load_default_context() perform_search(self.request, c, repo_group_name=self.db_repo_group_name) diff --git a/rhodecode/apps/ssh_support/__init__.py b/rhodecode/apps/ssh_support/__init__.py index 9621d032..b72a9e35 100644 --- a/rhodecode/apps/ssh_support/__init__.py +++ b/rhodecode/apps/ssh_support/__init__.py @@ -31,18 +31,18 @@ def _sanitize_settings_and_apply_defaults(settings): """ settings_maker = SettingsMaker(settings) - settings_maker.make_setting(config_keys.generate_authorized_keyfile, False, parser='bool') - settings_maker.make_setting(config_keys.wrapper_allow_shell, False, parser='bool') - settings_maker.make_setting(config_keys.enable_debug_logging, False, parser='bool') - settings_maker.make_setting(config_keys.ssh_key_generator_enabled, True, parser='bool') + settings_maker.make_setting(config_keys.generate_authorized_keyfile, False, parser="bool") + settings_maker.make_setting(config_keys.wrapper_allow_shell, False, parser="bool") + settings_maker.make_setting(config_keys.enable_debug_logging, False, parser="bool") + settings_maker.make_setting(config_keys.ssh_key_generator_enabled, True, parser="bool") - settings_maker.make_setting(config_keys.authorized_keys_file_path, '~/.ssh/authorized_keys_rhodecode') - settings_maker.make_setting(config_keys.wrapper_cmd, '/usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper-v2') - settings_maker.make_setting(config_keys.authorized_keys_line_ssh_opts, '') + settings_maker.make_setting(config_keys.authorized_keys_file_path, "~/.ssh/authorized_keys_rhodecode") + settings_maker.make_setting(config_keys.wrapper_cmd, "/usr/local/bin/rhodecode_bin/bin/rc-ssh-wrapper-v2") + settings_maker.make_setting(config_keys.authorized_keys_line_ssh_opts, "") - settings_maker.make_setting(config_keys.ssh_hg_bin, '/usr/local/bin/rhodecode_bin/vcs_bin/hg') - settings_maker.make_setting(config_keys.ssh_git_bin, '/usr/local/bin/rhodecode_bin/vcs_bin/git') - settings_maker.make_setting(config_keys.ssh_svn_bin, '/usr/local/bin/rhodecode_bin/vcs_bin/svnserve') + settings_maker.make_setting(config_keys.ssh_hg_bin, "/usr/local/bin/rhodecode_bin/vcs_bin/hg") + settings_maker.make_setting(config_keys.ssh_git_bin, "/usr/local/bin/rhodecode_bin/vcs_bin/git") + settings_maker.make_setting(config_keys.ssh_svn_bin, "/usr/local/bin/rhodecode_bin/vcs_bin/svnserve") settings_maker.env_expand() @@ -56,5 +56,5 @@ def includeme(config): # lazy import here for faster code reading... via sshwrapper-v2 mode from .subscribers import generate_ssh_authorized_keys_file_subscriber from .events import SshKeyFileChangeEvent - config.add_subscriber( - generate_ssh_authorized_keys_file_subscriber, SshKeyFileChangeEvent) + + config.add_subscriber(generate_ssh_authorized_keys_file_subscriber, SshKeyFileChangeEvent) diff --git a/rhodecode/apps/ssh_support/config_keys.py b/rhodecode/apps/ssh_support/config_keys.py index 26fead88..229fcd9c 100644 --- a/rhodecode/apps/ssh_support/config_keys.py +++ b/rhodecode/apps/ssh_support/config_keys.py @@ -19,14 +19,14 @@ # Definition of setting keys used to configure this module. Defined here to # avoid repetition of keys throughout the module. -generate_authorized_keyfile = 'ssh.generate_authorized_keyfile' -authorized_keys_file_path = 'ssh.authorized_keys_file_path' -authorized_keys_line_ssh_opts = 'ssh.authorized_keys_ssh_opts' -ssh_key_generator_enabled = 'ssh.enable_ui_key_generator' -wrapper_cmd = 'ssh.wrapper_cmd.v2' -wrapper_allow_shell = 'ssh.wrapper_cmd_allow_shell' -enable_debug_logging = 'ssh.enable_debug_logging' +generate_authorized_keyfile = "ssh.generate_authorized_keyfile" +authorized_keys_file_path = "ssh.authorized_keys_file_path" +authorized_keys_line_ssh_opts = "ssh.authorized_keys_ssh_opts" +ssh_key_generator_enabled = "ssh.enable_ui_key_generator" +wrapper_cmd = "ssh.wrapper_cmd.v2" +wrapper_allow_shell = "ssh.wrapper_cmd_allow_shell" +enable_debug_logging = "ssh.enable_debug_logging" -ssh_hg_bin = 'ssh.executable.hg' -ssh_git_bin = 'ssh.executable.git' -ssh_svn_bin = 'ssh.executable.svn' +ssh_hg_bin = "ssh.executable.hg" +ssh_git_bin = "ssh.executable.git" +ssh_svn_bin = "ssh.executable.svn" diff --git a/rhodecode/apps/ssh_support/events.py b/rhodecode/apps/ssh_support/events.py index 51b7dd7c..d36db77b 100644 --- a/rhodecode/apps/ssh_support/events.py +++ b/rhodecode/apps/ssh_support/events.py @@ -25,5 +25,6 @@ class SshKeyFileChangeEvent(RhodecodeEvent): """ This event will be triggered on every modification of the stored SSH keys """ - name = 'rhodecode-ssh-key-file-change' - display_name = _('RhodeCode SSH Key files changed.') + + name = "rhodecode-ssh-key-file-change" + display_name = _("RhodeCode SSH Key files changed.") diff --git a/rhodecode/apps/ssh_support/lib/backends/base.py b/rhodecode/apps/ssh_support/lib/backends/base.py index 0d824285..0def3f8e 100644 --- a/rhodecode/apps/ssh_support/lib/backends/base.py +++ b/rhodecode/apps/ssh_support/lib/backends/base.py @@ -34,8 +34,8 @@ class SshVcsServer(object): backend = None # set in child classes tunnel = None # subprocess handling tunnel settings = None # parsed settings module - write_perms = ['repository.admin', 'repository.write'] - read_perms = ['repository.read', 'repository.admin', 'repository.write'] + write_perms = ["repository.admin", "repository.write"] + read_perms = ["repository.read", "repository.admin", "repository.write"] def __init__(self, user, user_permissions, settings, env): self.user = user @@ -46,8 +46,8 @@ class SshVcsServer(object): self.repo_name = None self.repo_mode = None - self.store = '' - self.ini_path = '' + self.store = "" + self.ini_path = "" self.hooks_protocol = None def _invalidate_cache(self, repo_name): @@ -58,74 +58,69 @@ class SshVcsServer(object): """ # Todo: Leave only "celery" case after transition. match self.hooks_protocol: - case 'http': + case "http": from rhodecode.model.scm import ScmModel + ScmModel().mark_for_invalidation(repo_name) - case 'celery': - call_service_api(self.settings, { - "method": "service_mark_for_invalidation", - "args": {"repo_name": repo_name} - }) + case "celery": + call_service_api( + self.settings, {"method": "service_mark_for_invalidation", "args": {"repo_name": repo_name}} + ) def has_write_perm(self): permission = self.user_permissions.get(self.repo_name) - if permission in ['repository.write', 'repository.admin']: + if permission in ["repository.write", "repository.admin"]: return True return False def _check_permissions(self, action): permission = self.user_permissions.get(self.repo_name) - user_info = f'{self.user["user_id"]}:{self.user["username"]}' - log.debug('permission for %s on %s are: %s', - user_info, self.repo_name, permission) + user_info = f"{self.user['user_id']}:{self.user['username']}" + log.debug("permission for %s on %s are: %s", user_info, self.repo_name, permission) if not permission: - log.error('user `%s` permissions to repo:%s are empty. Forbidding access.', - user_info, self.repo_name) + log.error("user `%s` permissions to repo:%s are empty. Forbidding access.", user_info, self.repo_name) return -2 - if action == 'pull': + if action == "pull": if permission in self.read_perms: - log.info( - 'READ Permissions for User "%s" detected to repo "%s"!', - user_info, self.repo_name) + log.info('READ Permissions for User "%s" detected to repo "%s"!', user_info, self.repo_name) return 0 else: if permission in self.write_perms: - log.info( - 'WRITE, or Higher Permissions for User "%s" detected to repo "%s"!', - user_info, self.repo_name) + log.info('WRITE, or Higher Permissions for User "%s" detected to repo "%s"!', user_info, self.repo_name) return 0 - log.error('Cannot properly fetch or verify user `%s` permissions. ' - 'Permissions: %s, vcs action: %s', - user_info, permission, action) + log.error( + "Cannot properly fetch or verify user `%s` permissions. Permissions: %s, vcs action: %s", + user_info, + permission, + action, + ) return -2 def update_environment(self, action, extras=None): - scm_data = { - 'ip': os.environ['SSH_CLIENT'].split()[0], - 'username': self.user.username, - 'user_id': self.user.user_id, - 'action': action, - 'repository': self.repo_name, - 'scm': self.backend, - 'config': self.ini_path, - 'repo_store': self.store, - 'make_lock': None, - 'locked_by': [None, None], - 'server_url': None, - 'user_agent': f'{self.repo_user_agent}/ssh-user-agent', - 'hooks': ['push', 'pull'], - 'hooks_module': 'rhodecode.lib.hook_daemon.hook_module', - 'is_shadow_repo': False, - 'detect_force_push': False, - 'check_branch_perms': False, - - 'SSH': True, - 'SSH_PERMISSIONS': self.user_permissions.get(self.repo_name), + "ip": os.environ["SSH_CLIENT"].split()[0], + "username": self.user.username, + "user_id": self.user.user_id, + "action": action, + "repository": self.repo_name, + "scm": self.backend, + "config": self.ini_path, + "repo_store": self.store, + "make_lock": None, + "locked_by": [None, None], + "server_url": None, + "user_agent": f"{self.repo_user_agent}/ssh-user-agent", + "hooks": ["push", "pull"], + "hooks_module": "rhodecode.lib.hook_daemon.hook_module", + "is_shadow_repo": False, + "detect_force_push": False, + "check_branch_perms": False, + "SSH": True, + "SSH_PERMISSIONS": self.user_permissions.get(self.repo_name), } if extras: scm_data.update(extras) @@ -134,30 +129,30 @@ class SshVcsServer(object): def get_root_store(self): root_store = self.store - if not root_store.endswith('/'): + if not root_store.endswith("/"): # always append trailing slash - root_store = root_store + '/' + root_store = root_store + "/" return root_store def _handle_tunnel(self, extras): # pre-auth - action = 'pull' + action = "pull" exit_code = self._check_permissions(action) if exit_code: return exit_code, False - req = self.env.get('request') + req = self.env.get("request") if req: server_url = req.host_url + req.script_name - extras['server_url'] = server_url + extras["server_url"] = server_url - log.debug('Using %s binaries from path %s', self.backend, self._path) + log.debug("Using %s binaries from path %s", self.backend, self._path) exit_code = self.tunnel.run(extras) return exit_code, action == "push" def run(self, tunnel_extras=None): - self.hooks_protocol = self.settings['vcs.hooks.protocol.v2'] + self.hooks_protocol = self.settings["vcs.hooks.protocol.v2"] tunnel_extras = tunnel_extras or {} extras = {} extras.update(tunnel_extras) @@ -168,6 +163,6 @@ class SshVcsServer(object): try: return self._handle_tunnel(extras) finally: - log.debug('Running cleanup with cache invalidation') + log.debug("Running cleanup with cache invalidation") if self.repo_name: self._invalidate_cache(self.repo_name) diff --git a/rhodecode/apps/ssh_support/lib/backends/git.py b/rhodecode/apps/ssh_support/lib/backends/git.py index 47ded5df..81c69b1f 100644 --- a/rhodecode/apps/ssh_support/lib/backends/git.py +++ b/rhodecode/apps/ssh_support/lib/backends/git.py @@ -40,8 +40,8 @@ class GitTunnelWrapper(object): def command(self): root = self.server.get_root_store() command = "cd {root}; {git_path} {mode} '{root}{repo_name}'".format( - root=root, git_path=self.server.git_path, - mode=self.server.repo_mode, repo_name=self.server.repo_name) + root=root, git_path=self.server.git_path, mode=self.server.repo_mode, repo_name=self.server.repo_name + ) log.debug("Final CMD: %s", command) return command @@ -71,8 +71,8 @@ class GitTunnelWrapper(object): class GitServer(SshVcsServer): - backend = 'git' - repo_user_agent = 'git' + backend = "git" + repo_user_agent = "git" def __init__(self, store, ini_path, repo_name, repo_mode, user, user_permissions, settings, env): super().__init__(user, user_permissions, settings, env) @@ -80,7 +80,7 @@ class GitServer(SshVcsServer): self.store = store self.ini_path = ini_path self.repo_name = repo_name - self._path = self.git_path = settings['ssh.executable.git'] + self._path = self.git_path = settings["ssh.executable.git"] self.repo_mode = repo_mode self.tunnel = GitTunnelWrapper(server=self) diff --git a/rhodecode/apps/ssh_support/lib/backends/hg.py b/rhodecode/apps/ssh_support/lib/backends/hg.py index 0a99283b..cd3266ca 100644 --- a/rhodecode/apps/ssh_support/lib/backends/hg.py +++ b/rhodecode/apps/ssh_support/lib/backends/hg.py @@ -37,31 +37,31 @@ class MercurialTunnelWrapper(object): self.server = server self.stdin = sys.stdin self.stdout = sys.stdout - self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp(prefix='hgrc_rhodecode_') + self.hooks_env_fd, self.hooks_env_path = tempfile.mkstemp(prefix="hgrc_rhodecode_") def create_hooks_env(self): repo_name = self.server.repo_name hg_flags = self.server.config_to_hgrc(repo_name) content = textwrap.dedent( - ''' + """ # RhodeCode SSH hooks version=2.0.0 {custom} - ''' - ).format(custom='\n'.join(hg_flags)) + """ + ).format(custom="\n".join(hg_flags)) root = self.server.get_root_store() - hgrc_custom = os.path.join(root, repo_name, '.hg', 'hgrc_rhodecode') - hgrc_main = os.path.join(root, repo_name, '.hg', 'hgrc') + hgrc_custom = os.path.join(root, repo_name, ".hg", "hgrc_rhodecode") + hgrc_main = os.path.join(root, repo_name, ".hg", "hgrc") # cleanup custom hgrc file if os.path.isfile(hgrc_custom): - with open(hgrc_custom, 'wb') as f: - f.write(b'') - log.debug('Cleanup custom hgrc file under %s', hgrc_custom) + with open(hgrc_custom, "wb") as f: + f.write(b"") + log.debug("Cleanup custom hgrc file under %s", hgrc_custom) # write temp - with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file: + with os.fdopen(self.hooks_env_fd, "w") as hooks_env_file: hooks_env_file.write(content) return self.hooks_env_path @@ -72,18 +72,16 @@ class MercurialTunnelWrapper(object): def command(self, hgrc_path): root = self.server.get_root_store() - command = ( - "cd {root}; HGRCPATH={hgrc} {hg_path} -R {root}{repo_name} " - "serve --stdio".format( - root=root, hg_path=self.server.hg_path, - repo_name=self.server.repo_name, hgrc=hgrc_path)) + command = "cd {root}; HGRCPATH={hgrc} {hg_path} -R {root}{repo_name} serve --stdio".format( + root=root, hg_path=self.server.hg_path, repo_name=self.server.repo_name, hgrc=hgrc_path + ) log.debug("Final CMD: %s", command) return command def run(self, extras): # at this point we cannot tell, we do further ACL checks # inside the hooks - action = '?' + action = "?" # permissions are check via `pre_push_ssh_auth` hook self.server.update_environment(action=action, extras=extras) custom_hgrc_file = self.create_hooks_env() @@ -95,9 +93,9 @@ class MercurialTunnelWrapper(object): class MercurialServer(SshVcsServer): - backend = 'hg' - repo_user_agent = 'mercurial' - cli_flags = ['phases', 'largefiles', 'extensions', 'experimental', 'hooks'] + backend = "hg" + repo_user_agent = "mercurial" + cli_flags = ["phases", "largefiles", "extensions", "experimental", "hooks"] def __init__(self, store, ini_path, repo_name, user, user_permissions, settings, env): super().__init__(user, user_permissions, settings, env) @@ -105,35 +103,35 @@ class MercurialServer(SshVcsServer): self.store = store self.ini_path = ini_path self.repo_name = repo_name - self._path = self.hg_path = settings['ssh.executable.hg'] + self._path = self.hg_path = settings["ssh.executable.hg"] self.tunnel = MercurialTunnelWrapper(server=self) def config_to_hgrc(self, repo_name): # Todo: once transition is done only call to service api should exist - if self.hooks_protocol == 'celery': - data = call_service_api(self.settings, { - "method": "service_config_to_hgrc", - "args": {"cli_flags": self.cli_flags, "repo_name": repo_name} - }) - return data['flags'] + if self.hooks_protocol == "celery": + data = call_service_api( + self.settings, + {"method": "service_config_to_hgrc", "args": {"cli_flags": self.cli_flags, "repo_name": repo_name}}, + ) + return data["flags"] else: from rhodecode.model.db import RhodeCodeUi from rhodecode.model.settings import VcsSettingsModel + ui_sections = collections.defaultdict(list) ui = VcsSettingsModel(repo=repo_name).get_ui_settings(section=None, key=None) # write default hooks default_hooks = [ - ('pretxnchangegroup.ssh_auth', 'python:vcsserver.hooks.pre_push_ssh_auth'), - ('pretxnchangegroup.ssh', 'python:vcsserver.hooks.pre_push_ssh'), - ('changegroup.ssh', 'python:vcsserver.hooks.post_push_ssh'), - - ('preoutgoing.ssh', 'python:vcsserver.hooks.pre_pull_ssh'), - ('outgoing.ssh', 'python:vcsserver.hooks.post_pull_ssh'), + ("pretxnchangegroup.ssh_auth", "python:vcsserver.hooks.pre_push_ssh_auth"), + ("pretxnchangegroup.ssh", "python:vcsserver.hooks.pre_push_ssh"), + ("changegroup.ssh", "python:vcsserver.hooks.post_push_ssh"), + ("preoutgoing.ssh", "python:vcsserver.hooks.pre_pull_ssh"), + ("outgoing.ssh", "python:vcsserver.hooks.post_pull_ssh"), ] for k, v in default_hooks: - ui_sections['hooks'].append((k, v)) + ui_sections["hooks"].append((k, v)) for entry in ui: if not entry.active: @@ -143,15 +141,15 @@ class MercurialServer(SshVcsServer): if sec in self.cli_flags: # we want only custom hooks, so we skip builtins - if sec == 'hooks' and key in RhodeCodeUi.HOOKS_BUILTIN: + if sec == "hooks" and key in RhodeCodeUi.HOOKS_BUILTIN: continue ui_sections[sec].append([key, entry.value]) flags = [] for _sec, key_val in ui_sections.items(): - flags.append(' ') - flags.append(f'[{_sec}]') + flags.append(" ") + flags.append(f"[{_sec}]") for key, val in key_val: - flags.append(f'{key}= {val}') + flags.append(f"{key}= {val}") return flags diff --git a/rhodecode/apps/ssh_support/lib/backends/svn.py b/rhodecode/apps/ssh_support/lib/backends/svn.py index d56b8be3..dc09a27d 100644 --- a/rhodecode/apps/ssh_support/lib/backends/svn.py +++ b/rhodecode/apps/ssh_support/lib/backends/svn.py @@ -45,19 +45,15 @@ class SubversionTunnelWrapper(object): self.read_only = True # flag that we set to make the hooks readonly def create_svn_config(self): - content = ( - '[general]\n' - 'hooks-env = {}\n').format(self.hooks_env_path) - with os.fdopen(self.svn_conf_fd, 'w') as config_file: + content = ("[general]\nhooks-env = {}\n").format(self.hooks_env_path) + with os.fdopen(self.svn_conf_fd, "w") as config_file: config_file.write(content) def create_hooks_env(self): - content = ( - '[default]\n' - 'LANG = en_US.UTF-8\n') + content = "[default]\nLANG = en_US.UTF-8\n" if self.read_only: - content += 'SSH_READ_ONLY = 1\n' - with os.fdopen(self.hooks_env_fd, 'w') as hooks_env_file: + content += "SSH_READ_ONLY = 1\n" + with os.fdopen(self.hooks_env_fd, "w") as hooks_env_file: hooks_env_file.write(content) def remove_configs(self): @@ -69,16 +65,21 @@ class SubversionTunnelWrapper(object): username = self.server.user.username command = [ - self.server.svn_path, '-t', - '--config-file', self.svn_conf_path, - '--tunnel-user', username, - '-r', root] - log.debug("Final CMD: %s", ' '.join(command)) + self.server.svn_path, + "-t", + "--config-file", + self.svn_conf_path, + "--tunnel-user", + username, + "-r", + root, + ] + log.debug("Final CMD: %s", " ".join(command)) return command def start(self): command = self.command() - self.process = Popen(' '.join(command), stdin=PIPE, shell=True) + self.process = Popen(" ".join(command), stdin=PIPE, shell=True) def sync(self): while self.process.poll() is None: @@ -97,26 +98,19 @@ class SubversionTunnelWrapper(object): signal.alarm(self.timeout) first_response = self._read_first_client_response() signal.alarm(0) - return (self._parse_first_client_response(first_response) - if first_response else None) + return self._parse_first_client_response(first_response) if first_response else None def patch_first_client_response(self, response, **kwargs): self.create_hooks_env() - version = response['version'] - capabilities = response['capabilities'] - client = response['client'] or b'' + version = response["version"] + capabilities = response["capabilities"] + client = response["client"] or b"" - url = self._svn_bytes(response['url']) - ra_client = self._svn_bytes(response['ra_client']) + url = self._svn_bytes(response["url"]) + ra_client = self._svn_bytes(response["ra_client"]) - buffer_ = b"( %b ( %b ) %b%b( %b) ) " % ( - version, - capabilities, - url, - ra_client, - client - ) + buffer_ = b"( %b ( %b ) %b%b( %b) ) " % (version, capabilities, url, ra_client, client) self.process.stdin.write(buffer_) def fail(self, message): @@ -132,9 +126,9 @@ class SubversionTunnelWrapper(object): def _svn_bytes(self, bytes_: bytes) -> bytes: if not bytes_: - return b'' + return b"" - return f'{len(bytes_)}:'.encode() + bytes_ + b' ' + return f"{len(bytes_)}:".encode() + bytes_ + b" " def _read_first_client_response(self): buffer_ = b"" @@ -161,19 +155,14 @@ class SubversionTunnelWrapper(object): Please check https://svn.apache.org/repos/asf/subversion/trunk/subversion/libsvn_ra_svn/protocol """ - version_re = br'(?P\d+)' - capabilities_re = br'\(\s(?P[\w\d\-\ ]+)\s\)' - url_re = br'\d+\:(?P[\W\w]+)' - ra_client_re = br'(\d+\:(?P[\W\w]+)\s)' - client_re = br'(\d+\:(?P[\W\w]+)\s)*' + version_re = rb"(?P\d+)" + capabilities_re = rb"\(\s(?P[\w\d\-\ ]+)\s\)" + url_re = rb"\d+\:(?P[\W\w]+)" + ra_client_re = rb"(\d+\:(?P[\W\w]+)\s)" + client_re = rb"(\d+\:(?P[\W\w]+)\s)*" regex = re.compile( - br'^\(\s%b\s%b\s%b\s%b' - br'\(\s%b\)\s\)\s*$' % ( - version_re, - capabilities_re, - url_re, - ra_client_re, - client_re) + rb"^\(\s%b\s%b\s%b\s%b" + rb"\(\s%b\)\s\)\s*$" % (version_re, capabilities_re, url_re, ra_client_re, client_re) ) matcher = regex.match(buffer_) @@ -190,23 +179,22 @@ class SubversionTunnelWrapper(object): if url in self.server.user_permissions: return url - log.debug('Extracting repository name from subdir path %s', url) + log.debug("Extracting repository name from subdir path %s", url) # case 2 we check all permissions, and match closes possible case... # NOTE(dan): In this case we only know that url has a subdir parts, it's safe # to assume that it will have the repo name as prefix, we ensure the prefix # for similar repositories isn't matched by adding a / # e.g subgroup/repo-name/ and subgroup/repo-name-1/ would work correct. for repo_name in self.server.user_permissions: - repo_name_prefix = repo_name + '/' + repo_name_prefix = repo_name + "/" if url.startswith(repo_name_prefix): - log.debug('Found prefix %s match, returning proper repository name', - repo_name_prefix) + log.debug("Found prefix %s match, returning proper repository name", repo_name_prefix) return repo_name return def run(self, extras): - action = 'pull' + action = "pull" self.create_svn_config() self.start() @@ -214,9 +202,9 @@ class SubversionTunnelWrapper(object): if not first_response: return self.fail(b"Repository name cannot be extracted") - url_parts = urllib.parse.urlparse(first_response['url']) + url_parts = urllib.parse.urlparse(first_response["url"]) - self.server.repo_name = self._match_repo_name(safe_str(url_parts.path).strip('/')) + self.server.repo_name = self._match_repo_name(safe_str(url_parts.path).strip("/")) exit_code = self.server._check_permissions(action) if exit_code: @@ -233,8 +221,8 @@ class SubversionTunnelWrapper(object): class SubversionServer(SshVcsServer): - backend = 'svn' - repo_user_agent = 'svn' + backend = "svn" + repo_user_agent = "svn" def __init__(self, store, ini_path, repo_name, user, user_permissions, settings, env): super().__init__(user, user_permissions, settings, env) @@ -243,27 +231,24 @@ class SubversionServer(SshVcsServer): # NOTE(dan): repo_name at this point is empty, # this is set later in .run() based from parsed input stream self.repo_name = repo_name - self._path = self.svn_path = settings['ssh.executable.svn'] + self._path = self.svn_path = settings["ssh.executable.svn"] self.tunnel = SubversionTunnelWrapper(server=self) def _handle_tunnel(self, extras): - # pre-auth - action = 'pull' + action = "pull" # Special case for SVN, we extract repo name at later stage # exit_code = self._check_permissions(action) # if exit_code: # return exit_code, False - req = self.env.get('request') + req = self.env.get("request") if req: server_url = req.host_url + req.script_name - extras['server_url'] = server_url + extras["server_url"] = server_url - log.debug('Using %s binaries from path %s', self.backend, self._path) + log.debug("Using %s binaries from path %s", self.backend, self._path) exit_code = self.tunnel.run(extras) return exit_code, action == "push" - - diff --git a/rhodecode/apps/ssh_support/lib/ssh_wrapper_v1.py b/rhodecode/apps/ssh_support/lib/ssh_wrapper_v1.py index 7fb1f1cb..03c51bae 100644 --- a/rhodecode/apps/ssh_support/lib/ssh_wrapper_v1.py +++ b/rhodecode/apps/ssh_support/lib/ssh_wrapper_v1.py @@ -32,41 +32,45 @@ log = logging.getLogger(__name__) @click.command() -@click.argument('ini_path', type=click.Path(exists=True)) +@click.argument("ini_path", type=click.Path(exists=True)) @click.option( - '--mode', '-m', required=False, default='auto', - type=click.Choice(['auto', 'vcs', 'git', 'hg', 'svn', 'test']), - help='mode of operation') -@click.option('--user', help='Username for which the command will be executed') -@click.option('--user-id', help='User ID for which the command will be executed') -@click.option('--key-id', help='ID of the key from the database') -@click.option('--shell', '-s', is_flag=True, help='Allow Shell') -@click.option('--debug', is_flag=True, help='Enabled detailed output logging') + "--mode", + "-m", + required=False, + default="auto", + type=click.Choice(["auto", "vcs", "git", "hg", "svn", "test"]), + help="mode of operation", +) +@click.option("--user", help="Username for which the command will be executed") +@click.option("--user-id", help="User ID for which the command will be executed") +@click.option("--key-id", help="ID of the key from the database") +@click.option("--shell", "-s", is_flag=True, help="Allow Shell") +@click.option("--debug", is_flag=True, help="Enabled detailed output logging") def main(ini_path, mode, user, user_id, key_id, shell, debug): setup_custom_logging(ini_path, debug) - command = os.environ.get('SSH_ORIGINAL_COMMAND', '') - if not command and mode not in ['test']: + command = os.environ.get("SSH_ORIGINAL_COMMAND", "") + if not command and mode not in ["test"]: raise ValueError( - 'Unable to fetch SSH_ORIGINAL_COMMAND from environment.' - 'Please make sure this is set and available during execution ' - 'of this script.') - connection_info = os.environ.get('SSH_CONNECTION', '') + "Unable to fetch SSH_ORIGINAL_COMMAND from environment." + "Please make sure this is set and available during execution " + "of this script." + ) + connection_info = os.environ.get("SSH_CONNECTION", "") time_start = time.time() - with bootstrap(ini_path, env={'RC_CMD_SSH_WRAPPER': '1'}) as env: - settings = env['registry'].settings + with bootstrap(ini_path, env={"RC_CMD_SSH_WRAPPER": "1"}) as env: + settings = env["registry"].settings statsd = StatsdClient.statsd try: ssh_wrapper = SshWrapper( - command, connection_info, mode, - user, user_id, key_id, shell, ini_path, settings, env) + command, connection_info, mode, user, user_id, key_id, shell, ini_path, settings, env + ) except Exception: - log.exception('Failed to execute SshWrapper') + log.exception("Failed to execute SshWrapper") sys.exit(-5) return_code = ssh_wrapper.wrap() operation_took = time.time() - time_start if statsd: operation_took_ms = round(1000.0 * operation_took) - statsd.timing("rhodecode_ssh_wrapper_timing.histogram", operation_took_ms, - use_decimals=False) + statsd.timing("rhodecode_ssh_wrapper_timing.histogram", operation_took_ms, use_decimals=False) sys.exit(return_code) diff --git a/rhodecode/apps/ssh_support/lib/ssh_wrapper_v2.py b/rhodecode/apps/ssh_support/lib/ssh_wrapper_v2.py index bbfa7d25..060a2cd1 100644 --- a/rhodecode/apps/ssh_support/lib/ssh_wrapper_v2.py +++ b/rhodecode/apps/ssh_support/lib/ssh_wrapper_v2.py @@ -44,55 +44,62 @@ log = logging.getLogger(__name__) @click.command() -@click.argument('ini_path', type=click.Path(exists=True)) +@click.argument("ini_path", type=click.Path(exists=True)) @click.option( - '--mode', '-m', required=False, default='auto', - type=click.Choice(['auto', 'vcs', 'git', 'hg', 'svn', 'test']), - help='mode of operation') -@click.option('--user', help='Username for which the command will be executed') -@click.option('--user-id', help='User ID for which the command will be executed') -@click.option('--key-id', help='ID of the key from the database') -@click.option('--shell', '-s', is_flag=True, help='Allow Shell') -@click.option('--debug', is_flag=True, help='Enabled detailed output logging') + "--mode", + "-m", + required=False, + default="auto", + type=click.Choice(["auto", "vcs", "git", "hg", "svn", "test"]), + help="mode of operation", +) +@click.option("--user", help="Username for which the command will be executed") +@click.option("--user-id", help="User ID for which the command will be executed") +@click.option("--key-id", help="ID of the key from the database") +@click.option("--shell", "-s", is_flag=True, help="Allow Shell") +@click.option("--debug", is_flag=True, help="Enabled detailed output logging") def main(ini_path, mode, user, user_id, key_id, shell, debug): - time_start = time.time() setup_custom_logging(ini_path, debug) - command = os.environ.get('SSH_ORIGINAL_COMMAND', '') - if not command and mode not in ['test']: + command = os.environ.get("SSH_ORIGINAL_COMMAND", "") + if not command and mode not in ["test"]: raise ValueError( - 'Unable to fetch SSH_ORIGINAL_COMMAND from environment.' - 'Please make sure this is set and available during execution ' - 'of this script.') + "Unable to fetch SSH_ORIGINAL_COMMAND from environment." + "Please make sure this is set and available during execution " + "of this script." + ) # initialize settings and get defaults settings = get_app_config_lightweight(ini_path) - settings = sanitize_settings_and_apply_defaults({'__file__': ini_path}, settings) + settings = sanitize_settings_and_apply_defaults({"__file__": ini_path}, settings) # init and bootstrap StatsdClient StatsdClient.setup(settings) statsd = StatsdClient.statsd try: - connection_info = os.environ.get('SSH_CONNECTION', '') - request = Request.blank('/', base_url=settings['app.base_url']) - request.user = AttributeDict({'username': user, - 'user_id': user_id, - 'ip_addr': connection_info.split(' ')[0] if connection_info else None}) - env = {'RC_CMD_SSH_WRAPPER': '1', 'request': request} + connection_info = os.environ.get("SSH_CONNECTION", "") + request = Request.blank("/", base_url=settings["app.base_url"]) + request.user = AttributeDict( + { + "username": user, + "user_id": user_id, + "ip_addr": connection_info.split(" ")[0] if connection_info else None, + } + ) + env = {"RC_CMD_SSH_WRAPPER": "1", "request": request} ssh_wrapper = SshWrapperStandalone( - command, connection_info, mode, - user, user_id, key_id, shell, ini_path, settings, env) + command, connection_info, mode, user, user_id, key_id, shell, ini_path, settings, env + ) except Exception: - log.exception('Failed to execute SshWrapper') + log.exception("Failed to execute SshWrapper") sys.exit(-5) return_code = ssh_wrapper.wrap() operation_took = time.time() - time_start if statsd: operation_took_ms = round(1000.0 * operation_took) - statsd.timing("rhodecode_ssh_wrapper_timing.histogram", operation_took_ms, - use_decimals=False) + statsd.timing("rhodecode_ssh_wrapper_timing.histogram", operation_took_ms, use_decimals=False) sys.exit(return_code) diff --git a/rhodecode/apps/ssh_support/lib/utils.py b/rhodecode/apps/ssh_support/lib/utils.py index c5ef3265..751ea1cf 100644 --- a/rhodecode/apps/ssh_support/lib/utils.py +++ b/rhodecode/apps/ssh_support/lib/utils.py @@ -22,13 +22,14 @@ import logging def setup_custom_logging(ini_path, debug): if debug: from pyramid.paster import setup_logging # Lazy import + # enabled rhodecode.ini controlled logging setup setup_logging(ini_path) else: # configure logging in a mode that doesn't print anything. # in case of regularly configured logging it gets printed out back # to the client doing an SSH command. - logger = logging.getLogger('') + logger = logging.getLogger("") null = logging.NullHandler() # add the handler to the root logger logger.handlers = [null] diff --git a/rhodecode/apps/ssh_support/tests/conftest.py b/rhodecode/apps/ssh_support/tests/conftest.py index 5797d900..743fda4e 100644 --- a/rhodecode/apps/ssh_support/tests/conftest.py +++ b/rhodecode/apps/ssh_support/tests/conftest.py @@ -27,23 +27,20 @@ from rhodecode.lib.utils2 import AttributeDict @pytest.fixture() def dummy_conf_file(tmpdir): conf = configparser.ConfigParser() - conf.add_section('app:main') - conf.set('app:main', 'ssh.executable.hg', '/usr/bin/hg') - conf.set('app:main', 'ssh.executable.git', '/usr/bin/git') - conf.set('app:main', 'ssh.executable.svn', '/usr/bin/svnserve') + conf.add_section("app:main") + conf.set("app:main", "ssh.executable.hg", "/usr/bin/hg") + conf.set("app:main", "ssh.executable.git", "/usr/bin/git") + conf.set("app:main", "ssh.executable.svn", "/usr/bin/svnserve") - f_path = os.path.join(str(tmpdir), 'ssh_wrapper_test.ini') - with open(f_path, 'wt') as f: + f_path = os.path.join(str(tmpdir), "ssh_wrapper_test.ini") + with open(f_path, "wt") as f: conf.write(f) return os.path.join(f_path) def plain_dummy_env(): - return { - 'request': - AttributeDict(host_url='http://localhost', script_name='/') - } + return {"request": AttributeDict(host_url="http://localhost", script_name="/")} @pytest.fixture() @@ -52,10 +49,7 @@ def dummy_env(): def plain_dummy_user(): - return AttributeDict( - user_id=1, - username='test_user' - ) + return AttributeDict(user_id=1, username="test_user") @pytest.fixture() @@ -65,7 +59,16 @@ def dummy_user(): @pytest.fixture() def ssh_wrapper(app, dummy_conf_file, dummy_env): - conn_info = '127.0.0.1 22 10.0.0.1 443' + conn_info = "127.0.0.1 22 10.0.0.1 443" return SshWrapper( - 'random command', conn_info, 'auto', 'admin', '1', key_id='1', - shell=False, ini_path=dummy_conf_file, settings={}, env=dummy_env) + "random command", + conn_info, + "auto", + "admin", + "1", + key_id="1", + shell=False, + ini_path=dummy_conf_file, + settings={}, + env=dummy_env, + ) diff --git a/rhodecode/apps/ssh_support/tests/test_server_git.py b/rhodecode/apps/ssh_support/tests/test_server_git.py index 9260f789..95cc4862 100644 --- a/rhodecode/apps/ssh_support/tests/test_server_git.py +++ b/rhodecode/apps/ssh_support/tests/test_server_git.py @@ -27,19 +27,19 @@ from rhodecode.lib.ext_json import json class GitServerCreator(object): - root = '/tmp/repo/path/' - git_path = '/usr/local/bin/git' + root = "/tmp/repo/path/" + git_path = "/usr/local/bin/git" config_data = { - 'app:main': { - 'ssh.executable.git': git_path, - 'vcs.hooks.protocol.v2': 'celery', - 'app.service_api.host': 'http://localhost', - 'app.service_api.token': 'secret4', - 'rhodecode.api.url': '/_admin/api', + "app:main": { + "ssh.executable.git": git_path, + "vcs.hooks.protocol.v2": "celery", + "app.service_api.host": "http://localhost", + "app.service_api.token": "secret4", + "rhodecode.api.url": "/_admin/api", } } - repo_name = 'test_git' - repo_mode = 'receive-pack' + repo_name = "test_git" + repo_mode = "receive-pack" user = plain_dummy_user() def __init__(self, service_api_url, ini_file): @@ -47,28 +47,26 @@ class GitServerCreator(object): self.ini_file = ini_file def create(self, **kwargs): - self.config_data['app:main']['app.service_api.host'] = self.service_api_url + self.config_data["app:main"]["app.service_api.host"] = self.service_api_url parameters = { - 'store': self.root, - 'ini_path': self.ini_file, - 'user': self.user, - 'repo_name': self.repo_name, - 'repo_mode': self.repo_mode, - 'user_permissions': { - self.repo_name: 'repository.admin' - }, - 'settings': self.config_data['app:main'], - 'env': plain_dummy_env() + "store": self.root, + "ini_path": self.ini_file, + "user": self.user, + "repo_name": self.repo_name, + "repo_mode": self.repo_mode, + "user_permissions": {self.repo_name: "repository.admin"}, + "settings": self.config_data["app:main"], + "env": plain_dummy_env(), } parameters.update(kwargs) server = GitServer(**parameters) return server -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def git_server(request, module_app, rhodecode_factory, available_port_factory): - ini_file = module_app._pyramid_settings['__file__'] - vcsserver_host = module_app._pyramid_settings['vcs.server'] + ini_file = module_app._pyramid_settings["__file__"] + vcsserver_host = module_app._pyramid_settings["vcs.server"] store_dir = os.path.dirname(ini_file) @@ -78,47 +76,52 @@ def git_server(request, module_app, rhodecode_factory, available_port_factory): store_dir=store_dir, port=available_port_factory(), overrides=( - {'handler_console': {'level': 'DEBUG'}}, - {'app:main': {'vcs.server': vcsserver_host}}, - {'app:main': {'repo_store.path': store_dir}} - )) + {"handler_console": {"level": "DEBUG"}}, + {"app:main": {"vcs.server": vcsserver_host}}, + {"app:main": {"repo_store.path": store_dir}}, + ), + ) - service_api_url = f'http://{rc.bind_addr}' + service_api_url = f"http://{rc.bind_addr}" return GitServerCreator(service_api_url, ini_file) class TestGitServer: - def test_command(self, git_server): server = git_server.create() - expected_command = ( - 'cd {root}; {git_path} {repo_mode} \'{root}{repo_name}\''.format( - root=git_server.root, git_path=git_server.git_path, - repo_mode=git_server.repo_mode, repo_name=git_server.repo_name) + expected_command = "cd {root}; {git_path} {repo_mode} '{root}{repo_name}'".format( + root=git_server.root, + git_path=git_server.git_path, + repo_mode=git_server.repo_mode, + repo_name=git_server.repo_name, ) assert expected_command == server.tunnel.command() - @pytest.mark.parametrize('permissions, action, code', [ - ({}, 'pull', -2), - ({'test_git': 'repository.read'}, 'pull', 0), - ({'test_git': 'repository.read'}, 'push', -2), - ({'test_git': 'repository.write'}, 'push', 0), - ({'test_git': 'repository.admin'}, 'push', 0), - - ]) + @pytest.mark.parametrize( + "permissions, action, code", + [ + ({}, "pull", -2), + ({"test_git": "repository.read"}, "pull", 0), + ({"test_git": "repository.read"}, "push", -2), + ({"test_git": "repository.write"}, "push", 0), + ({"test_git": "repository.admin"}, "push", 0), + ], + ) def test_permission_checks(self, git_server, permissions, action, code): server = git_server.create(user_permissions=permissions) result = server._check_permissions(action) assert result is code - @pytest.mark.parametrize('permissions, value', [ - ({}, False), - ({'test_git': 'repository.read'}, False), - ({'test_git': 'repository.write'}, True), - ({'test_git': 'repository.admin'}, True), - - ]) + @pytest.mark.parametrize( + "permissions, value", + [ + ({}, False), + ({"test_git": "repository.read"}, False), + ({"test_git": "repository.write"}, True), + ({"test_git": "repository.admin"}, True), + ], + ) def test_has_write_permissions(self, git_server, permissions, value): server = git_server.create(user_permissions=permissions) result = server.has_write_perm() @@ -126,49 +129,46 @@ class TestGitServer: def test_run_returns_executes_command(self, git_server): from rhodecode.apps.ssh_support.lib.backends.git import GitTunnelWrapper + server = git_server.create() - os.environ['SSH_CLIENT'] = '127.0.0.1' - with mock.patch.object(GitTunnelWrapper, 'create_hooks_env') as _patch: + os.environ["SSH_CLIENT"] = "127.0.0.1" + with mock.patch.object(GitTunnelWrapper, "create_hooks_env") as _patch: _patch.return_value = 0 - with mock.patch.object(GitTunnelWrapper, 'command', return_value='date'): - exit_code = server.run(tunnel_extras={'config': server.ini_path}) + with mock.patch.object(GitTunnelWrapper, "command", return_value="date"): + exit_code = server.run(tunnel_extras={"config": server.ini_path}) assert exit_code == (0, False) - @pytest.mark.parametrize( - 'repo_mode, action', [ - ['receive-pack', 'push'], - ['upload-pack', 'pull'] - ]) + @pytest.mark.parametrize("repo_mode, action", [["receive-pack", "push"], ["upload-pack", "pull"]]) def test_update_environment(self, git_server, repo_mode, action): server = git_server.create(repo_mode=repo_mode) store = server.store - with mock.patch('os.environ', {'SSH_CLIENT': '10.10.10.10 b'}): - with mock.patch('os.putenv') as putenv_mock: + with mock.patch("os.environ", {"SSH_CLIENT": "10.10.10.10 b"}): + with mock.patch("os.putenv") as putenv_mock: server.update_environment(action) expected_data = { - 'username': git_server.user.username, - 'user_id': git_server.user.user_id, - 'scm': 'git', - 'repository': git_server.repo_name, - 'make_lock': None, - 'action': action, - 'ip': '10.10.10.10', - 'locked_by': [None, None], - 'config': git_server.ini_file, - 'repo_store': store, - 'server_url': None, - 'hooks': ['push', 'pull'], - 'is_shadow_repo': False, - 'hooks_module': 'rhodecode.lib.hook_daemon.hook_module', - 'check_branch_perms': False, - 'detect_force_push': False, - 'user_agent': u'git/ssh-user-agent', - 'SSH': True, - 'SSH_PERMISSIONS': 'repository.admin', + "username": git_server.user.username, + "user_id": git_server.user.user_id, + "scm": "git", + "repository": git_server.repo_name, + "make_lock": None, + "action": action, + "ip": "10.10.10.10", + "locked_by": [None, None], + "config": git_server.ini_file, + "repo_store": store, + "server_url": None, + "hooks": ["push", "pull"], + "is_shadow_repo": False, + "hooks_module": "rhodecode.lib.hook_daemon.hook_module", + "check_branch_perms": False, + "detect_force_push": False, + "user_agent": "git/ssh-user-agent", + "SSH": True, + "SSH_PERMISSIONS": "repository.admin", } args, kwargs = putenv_mock.call_args assert json.loads(args[1]) == expected_data diff --git a/rhodecode/apps/ssh_support/tests/test_server_hg.py b/rhodecode/apps/ssh_support/tests/test_server_hg.py index d0521adc..3d7e2d2c 100644 --- a/rhodecode/apps/ssh_support/tests/test_server_hg.py +++ b/rhodecode/apps/ssh_support/tests/test_server_hg.py @@ -26,19 +26,19 @@ from rhodecode.apps.ssh_support.tests.conftest import plain_dummy_env, plain_dum class MercurialServerCreator(object): - root = '/tmp/repo/path/' - hg_path = '/usr/local/bin/hg' + root = "/tmp/repo/path/" + hg_path = "/usr/local/bin/hg" config_data = { - 'app:main': { - 'ssh.executable.hg': hg_path, - 'vcs.hooks.protocol.v2': 'celery', - 'app.service_api.host': 'http://localhost', - 'app.service_api.token': 'secret4', - 'rhodecode.api.url': '/_admin/api', + "app:main": { + "ssh.executable.hg": hg_path, + "vcs.hooks.protocol.v2": "celery", + "app.service_api.host": "http://localhost", + "app.service_api.token": "secret4", + "rhodecode.api.url": "/_admin/api", } } - repo_name = 'test_hg' + repo_name = "test_hg" user = plain_dummy_user() def __init__(self, service_api_url, ini_file): @@ -46,27 +46,25 @@ class MercurialServerCreator(object): self.ini_file = ini_file def create(self, **kwargs): - self.config_data['app:main']['app.service_api.host'] = self.service_api_url + self.config_data["app:main"]["app.service_api.host"] = self.service_api_url parameters = { - 'store': self.root, - 'ini_path': self.ini_file, - 'user': self.user, - 'repo_name': self.repo_name, - 'user_permissions': { - self.repo_name: 'repository.admin' - }, - 'settings': self.config_data['app:main'], - 'env': plain_dummy_env() + "store": self.root, + "ini_path": self.ini_file, + "user": self.user, + "repo_name": self.repo_name, + "user_permissions": {self.repo_name: "repository.admin"}, + "settings": self.config_data["app:main"], + "env": plain_dummy_env(), } parameters.update(kwargs) server = MercurialServer(**parameters) return server -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def hg_server(request, module_app, rhodecode_factory, available_port_factory): - ini_file = module_app._pyramid_settings['__file__'] - vcsserver_host = module_app._pyramid_settings['vcs.server'] + ini_file = module_app._pyramid_settings["__file__"] + vcsserver_host = module_app._pyramid_settings["vcs.server"] store_dir = os.path.dirname(ini_file) @@ -76,49 +74,51 @@ def hg_server(request, module_app, rhodecode_factory, available_port_factory): store_dir=store_dir, port=available_port_factory(), overrides=( - {'handler_console': {'level': 'DEBUG'}}, - {'app:main': {'vcs.server': vcsserver_host}}, - {'app:main': {'repo_store.path': store_dir}} - )) + {"handler_console": {"level": "DEBUG"}}, + {"app:main": {"vcs.server": vcsserver_host}}, + {"app:main": {"repo_store.path": store_dir}}, + ), + ) - service_api_url = f'http://{rc.bind_addr}' + service_api_url = f"http://{rc.bind_addr}" return MercurialServerCreator(service_api_url, ini_file) class TestMercurialServer: - def test_command(self, hg_server, tmpdir): server = hg_server.create() - custom_hgrc = os.path.join(str(tmpdir), 'hgrc') - expected_command = ( - 'cd {root}; HGRCPATH={custom_hgrc} {hg_path} -R {root}{repo_name} serve --stdio'.format( - root=hg_server.root, custom_hgrc=custom_hgrc, hg_path=hg_server.hg_path, - repo_name=hg_server.repo_name) + custom_hgrc = os.path.join(str(tmpdir), "hgrc") + expected_command = "cd {root}; HGRCPATH={custom_hgrc} {hg_path} -R {root}{repo_name} serve --stdio".format( + root=hg_server.root, custom_hgrc=custom_hgrc, hg_path=hg_server.hg_path, repo_name=hg_server.repo_name ) server_command = server.tunnel.command(custom_hgrc) assert expected_command == server_command - @pytest.mark.parametrize('permissions, action, code', [ - ({}, 'pull', -2), - ({'test_hg': 'repository.read'}, 'pull', 0), - ({'test_hg': 'repository.read'}, 'push', -2), - ({'test_hg': 'repository.write'}, 'push', 0), - ({'test_hg': 'repository.admin'}, 'push', 0), - - ]) + @pytest.mark.parametrize( + "permissions, action, code", + [ + ({}, "pull", -2), + ({"test_hg": "repository.read"}, "pull", 0), + ({"test_hg": "repository.read"}, "push", -2), + ({"test_hg": "repository.write"}, "push", 0), + ({"test_hg": "repository.admin"}, "push", 0), + ], + ) def test_permission_checks(self, hg_server, permissions, action, code): server = hg_server.create(user_permissions=permissions) result = server._check_permissions(action) assert result is code - @pytest.mark.parametrize('permissions, value', [ - ({}, False), - ({'test_hg': 'repository.read'}, False), - ({'test_hg': 'repository.write'}, True), - ({'test_hg': 'repository.admin'}, True), - - ]) + @pytest.mark.parametrize( + "permissions, value", + [ + ({}, False), + ({"test_hg": "repository.read"}, False), + ({"test_hg": "repository.write"}, True), + ({"test_hg": "repository.admin"}, True), + ], + ) def test_has_write_permissions(self, hg_server, permissions, value): server = hg_server.create(user_permissions=permissions) result = server.has_write_perm() @@ -127,13 +127,11 @@ class TestMercurialServer: def test_run_returns_executes_command(self, hg_server): server = hg_server.create() from rhodecode.apps.ssh_support.lib.backends.hg import MercurialTunnelWrapper - os.environ['SSH_CLIENT'] = '127.0.0.1' - with mock.patch.object(MercurialTunnelWrapper, 'create_hooks_env') as _patch: + + os.environ["SSH_CLIENT"] = "127.0.0.1" + with mock.patch.object(MercurialTunnelWrapper, "create_hooks_env") as _patch: _patch.return_value = 0 - with mock.patch.object(MercurialTunnelWrapper, 'command', return_value='date'): - exit_code = server.run(tunnel_extras={'config': server.ini_path}) + with mock.patch.object(MercurialTunnelWrapper, "command", return_value="date"): + exit_code = server.run(tunnel_extras={"config": server.ini_path}) assert exit_code == (0, False) - - - diff --git a/rhodecode/apps/ssh_support/tests/test_server_svn.py b/rhodecode/apps/ssh_support/tests/test_server_svn.py index a574cc7f..64017573 100644 --- a/rhodecode/apps/ssh_support/tests/test_server_svn.py +++ b/rhodecode/apps/ssh_support/tests/test_server_svn.py @@ -26,19 +26,19 @@ from rhodecode.apps.ssh_support.tests.conftest import plain_dummy_env, plain_dum class SubversionServerCreator(object): - root = '/tmp/repo/path/' - svn_path = '/usr/local/bin/svnserve' + root = "/tmp/repo/path/" + svn_path = "/usr/local/bin/svnserve" config_data = { - 'app:main': { - 'ssh.executable.svn': svn_path, - 'vcs.hooks.protocol.v2': 'celery', - 'app.service_api.host': 'http://localhost', - 'app.service_api.token': 'secret4', - 'rhodecode.api.url': '/_admin/api', + "app:main": { + "ssh.executable.svn": svn_path, + "vcs.hooks.protocol.v2": "celery", + "app.service_api.host": "http://localhost", + "app.service_api.token": "secret4", + "rhodecode.api.url": "/_admin/api", } } - repo_name = 'test-svn' + repo_name = "test-svn" user = plain_dummy_user() def __init__(self, service_api_url, ini_file): @@ -46,27 +46,25 @@ class SubversionServerCreator(object): self.ini_file = ini_file def create(self, **kwargs): - self.config_data['app:main']['app.service_api.host'] = self.service_api_url + self.config_data["app:main"]["app.service_api.host"] = self.service_api_url parameters = { - 'store': self.root, - 'ini_path': self.ini_file, - 'user': self.user, - 'repo_name': self.repo_name, - 'user_permissions': { - self.repo_name: 'repository.admin' - }, - 'settings': self.config_data['app:main'], - 'env': plain_dummy_env() + "store": self.root, + "ini_path": self.ini_file, + "user": self.user, + "repo_name": self.repo_name, + "user_permissions": {self.repo_name: "repository.admin"}, + "settings": self.config_data["app:main"], + "env": plain_dummy_env(), } parameters.update(kwargs) server = SubversionServer(**parameters) return server -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def svn_server(request, module_app, rhodecode_factory, available_port_factory): - ini_file = module_app._pyramid_settings['__file__'] - vcsserver_host = module_app._pyramid_settings['vcs.server'] + ini_file = module_app._pyramid_settings["__file__"] + vcsserver_host = module_app._pyramid_settings["vcs.server"] store_dir = os.path.dirname(ini_file) @@ -76,116 +74,123 @@ def svn_server(request, module_app, rhodecode_factory, available_port_factory): store_dir=store_dir, port=available_port_factory(), overrides=( - {'handler_console': {'level': 'DEBUG'}}, - {'app:main': {'vcs.server': vcsserver_host}}, - {'app:main': {'repo_store.path': store_dir}} - )) + {"handler_console": {"level": "DEBUG"}}, + {"app:main": {"vcs.server": vcsserver_host}}, + {"app:main": {"repo_store.path": store_dir}}, + ), + ) - service_api_url = f'http://{rc.bind_addr}' + service_api_url = f"http://{rc.bind_addr}" return SubversionServerCreator(service_api_url, ini_file) class TestSubversionServer(object): - def test_command(self, svn_server): server = svn_server.create() expected_command = [ - svn_server.svn_path, '-t', - '--config-file', server.tunnel.svn_conf_path, - '--tunnel-user', svn_server.user.username, - '-r', svn_server.root + svn_server.svn_path, + "-t", + "--config-file", + server.tunnel.svn_conf_path, + "--tunnel-user", + svn_server.user.username, + "-r", + svn_server.root, ] assert expected_command == server.tunnel.command() - @pytest.mark.parametrize('permissions, action, code', [ - ({}, 'pull', -2), - ({'test-svn': 'repository.read'}, 'pull', 0), - ({'test-svn': 'repository.read'}, 'push', -2), - ({'test-svn': 'repository.write'}, 'push', 0), - ({'test-svn': 'repository.admin'}, 'push', 0), - - ]) + @pytest.mark.parametrize( + "permissions, action, code", + [ + ({}, "pull", -2), + ({"test-svn": "repository.read"}, "pull", 0), + ({"test-svn": "repository.read"}, "push", -2), + ({"test-svn": "repository.write"}, "push", 0), + ({"test-svn": "repository.admin"}, "push", 0), + ], + ) def test_permission_checks(self, svn_server, permissions, action, code): server = svn_server.create(user_permissions=permissions) result = server._check_permissions(action) assert result is code - @pytest.mark.parametrize('permissions, access_paths, expected_match', [ - # not matched repository name - ({ - 'test-svn': '' - }, ['test-svn-1', 'test-svn-1/subpath'], - None), - - # exact match - ({ - 'test-svn': '' - }, - ['test-svn'], - 'test-svn'), - - # subdir commits - ({ - 'test-svn': '' - }, - ['test-svn/foo', - 'test-svn/foo/test-svn', - 'test-svn/trunk/development.txt', - ], - 'test-svn'), - - # subgroups + similar patterns - ({ - 'test-svn': '', - 'test-svn-1': '', - 'test-svn-subgroup/test-svn': '', - - }, - ['test-svn-1', - 'test-svn-1/foo/test-svn', - 'test-svn-1/test-svn', - ], - 'test-svn-1'), - - # subgroups + similar patterns - ({ - 'test-svn-1': '', - 'test-svn-10': '', - 'test-svn-100': '', - }, - ['test-svn-10', - 'test-svn-10/foo/test-svn', - 'test-svn-10/test-svn', - ], - 'test-svn-10'), - - # subgroups + similar patterns - ({ - 'name': '', - 'nameContains': '', - 'nameContainsThis': '', - }, - ['nameContains', - 'nameContains/This', - 'nameContains/This/test-svn', - ], - 'nameContains'), - - # subgroups + similar patterns - ({ - 'test-svn': '', - 'test-svn-1': '', - 'test-svn-subgroup/test-svn': '', - - }, - ['test-svn-subgroup/test-svn', - 'test-svn-subgroup/test-svn/foo/test-svn', - 'test-svn-subgroup/test-svn/trunk/example.txt', - ], - 'test-svn-subgroup/test-svn'), - ]) + @pytest.mark.parametrize( + "permissions, access_paths, expected_match", + [ + # not matched repository name + ({"test-svn": ""}, ["test-svn-1", "test-svn-1/subpath"], None), + # exact match + ({"test-svn": ""}, ["test-svn"], "test-svn"), + # subdir commits + ( + {"test-svn": ""}, + [ + "test-svn/foo", + "test-svn/foo/test-svn", + "test-svn/trunk/development.txt", + ], + "test-svn", + ), + # subgroups + similar patterns + ( + { + "test-svn": "", + "test-svn-1": "", + "test-svn-subgroup/test-svn": "", + }, + [ + "test-svn-1", + "test-svn-1/foo/test-svn", + "test-svn-1/test-svn", + ], + "test-svn-1", + ), + # subgroups + similar patterns + ( + { + "test-svn-1": "", + "test-svn-10": "", + "test-svn-100": "", + }, + [ + "test-svn-10", + "test-svn-10/foo/test-svn", + "test-svn-10/test-svn", + ], + "test-svn-10", + ), + # subgroups + similar patterns + ( + { + "name": "", + "nameContains": "", + "nameContainsThis": "", + }, + [ + "nameContains", + "nameContains/This", + "nameContains/This/test-svn", + ], + "nameContains", + ), + # subgroups + similar patterns + ( + { + "test-svn": "", + "test-svn-1": "", + "test-svn-subgroup/test-svn": "", + }, + [ + "test-svn-subgroup/test-svn", + "test-svn-subgroup/test-svn/foo/test-svn", + "test-svn-subgroup/test-svn/trunk/example.txt", + ], + "test-svn-subgroup/test-svn", + ), + ], + ) def test_repo_extraction_on_subdir(self, svn_server, permissions, access_paths, expected_match): server = svn_server.create(user_permissions=permissions) for path in access_paths: @@ -196,21 +201,14 @@ class TestSubversionServer(object): from rhodecode.apps.ssh_support.lib.backends.svn import SubversionTunnelWrapper server = svn_server.create() - os.environ['SSH_CLIENT'] = '127.0.0.1' + os.environ["SSH_CLIENT"] = "127.0.0.1" with mock.patch.object( - SubversionTunnelWrapper, 'get_first_client_response', - return_value={'url': 'http://server/test-svn'}): - with mock.patch.object( - SubversionTunnelWrapper, 'patch_first_client_response', - return_value=0): - with mock.patch.object( - SubversionTunnelWrapper, 'sync', - return_value=0): - with mock.patch.object( - SubversionTunnelWrapper, 'command', - return_value=['date']): - - exit_code = server.run(tunnel_extras={'config': server.ini_path}) + SubversionTunnelWrapper, "get_first_client_response", return_value={"url": "http://server/test-svn"} + ): + with mock.patch.object(SubversionTunnelWrapper, "patch_first_client_response", return_value=0): + with mock.patch.object(SubversionTunnelWrapper, "sync", return_value=0): + with mock.patch.object(SubversionTunnelWrapper, "command", return_value=["date"]): + exit_code = server.run(tunnel_extras={"config": server.ini_path}) # SVN has this differently configured, and we get in our mock env # None as return code assert exit_code == (None, False) @@ -219,9 +217,8 @@ class TestSubversionServer(object): from rhodecode.apps.ssh_support.lib.backends.svn import SubversionTunnelWrapper server = svn_server.create() - with mock.patch.object(SubversionTunnelWrapper, 'command', return_value=['date']): - with mock.patch.object(SubversionTunnelWrapper, 'get_first_client_response', - return_value=None): - exit_code = server.run(tunnel_extras={'config': server.ini_path}) + with mock.patch.object(SubversionTunnelWrapper, "command", return_value=["date"]): + with mock.patch.object(SubversionTunnelWrapper, "get_first_client_response", return_value=None): + exit_code = server.run(tunnel_extras={"config": server.ini_path}) assert exit_code == (1, False) diff --git a/rhodecode/apps/ssh_support/tests/test_ssh_authorized_keys_gen.py b/rhodecode/apps/ssh_support/tests/test_ssh_authorized_keys_gen.py index 13ba4adf..e1fec86a 100644 --- a/rhodecode/apps/ssh_support/tests/test_ssh_authorized_keys_gen.py +++ b/rhodecode/apps/ssh_support/tests/test_ssh_authorized_keys_gen.py @@ -25,27 +25,23 @@ from rhodecode.lib.utils2 import AttributeDict class TestSshKeyFileGeneration(object): - @pytest.mark.parametrize('ssh_wrapper_cmd', ['/tmp/sshwrapper.py']) - @pytest.mark.parametrize('allow_shell', [True, False]) - @pytest.mark.parametrize('debug', [True, False]) - @pytest.mark.parametrize('ssh_opts', [None, 'mycustom,option']) + @pytest.mark.parametrize("ssh_wrapper_cmd", ["/tmp/sshwrapper.py"]) + @pytest.mark.parametrize("allow_shell", [True, False]) + @pytest.mark.parametrize("debug", [True, False]) + @pytest.mark.parametrize("ssh_opts", [None, "mycustom,option"]) def test_write_keyfile(self, tmpdir, ssh_wrapper_cmd, allow_shell, debug, ssh_opts): - - authorized_keys_file_path = os.path.join(str(tmpdir), 'authorized_keys') + authorized_keys_file_path = os.path.join(str(tmpdir), "authorized_keys") def keys(): return [ - AttributeDict({'user': AttributeDict(username='admin'), - 'ssh_key_data': 'ssh-rsa ADMIN_KEY'}), - AttributeDict({'user': AttributeDict(username='user'), - 'ssh_key_data': 'ssh-rsa USER_KEY'}), + AttributeDict({"user": AttributeDict(username="admin"), "ssh_key_data": "ssh-rsa ADMIN_KEY"}), + AttributeDict({"user": AttributeDict(username="user"), "ssh_key_data": "ssh-rsa USER_KEY"}), ] - with mock.patch('rhodecode.apps.ssh_support.utils.get_all_active_keys', - return_value=keys()): - with mock.patch.dict('rhodecode.CONFIG', {'__file__': '/tmp/file.ini'}): + + with mock.patch("rhodecode.apps.ssh_support.utils.get_all_active_keys", return_value=keys()): + with mock.patch.dict("rhodecode.CONFIG", {"__file__": "/tmp/file.ini"}): utils._generate_ssh_authorized_keys_file( - authorized_keys_file_path, ssh_wrapper_cmd, - allow_shell, ssh_opts, debug + authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts, debug ) assert os.path.isfile(authorized_keys_file_path) @@ -53,17 +49,16 @@ class TestSshKeyFileGeneration(object): content = f.read() assert 'command="/tmp/sshwrapper.py' in content - assert 'This file is managed by RhodeCode, ' \ - 'please do not edit it manually.' in content + assert "This file is managed by RhodeCode, please do not edit it manually." in content if allow_shell: - assert '--shell' in content + assert "--shell" in content if debug: - assert '--debug' in content + assert "--debug" in content - assert '--user' in content - assert '--user-id' in content + assert "--user" in content + assert "--user-id" in content if ssh_opts: assert ssh_opts in content diff --git a/rhodecode/apps/ssh_support/tests/test_ssh_wrapper.py b/rhodecode/apps/ssh_support/tests/test_ssh_wrapper.py index e5df0134..5a2486a7 100644 --- a/rhodecode/apps/ssh_support/tests/test_ssh_wrapper.py +++ b/rhodecode/apps/ssh_support/tests/test_ssh_wrapper.py @@ -20,29 +20,32 @@ import pytest class TestSSHWrapper(object): - def test_serve_raises_an_exception_when_vcs_is_not_recognized(self, ssh_wrapper): with pytest.raises(Exception) as exc_info: ssh_wrapper.serve( - vcs='microsoft-tfs', repo='test-repo', mode=None, user='test', - permissions={}, branch_permissions={}) - assert str(exc_info.value) == 'Unrecognised VCS: microsoft-tfs' + vcs="microsoft-tfs", repo="test-repo", mode=None, user="test", permissions={}, branch_permissions={} + ) + assert str(exc_info.value) == "Unrecognised VCS: microsoft-tfs" def test_get_connection_info(self, ssh_wrapper): conn_info = ssh_wrapper.get_connection_info() - assert {'client_ip': '127.0.0.1', - 'client_port': '22', - 'server_ip': '10.0.0.1', - 'server_port': '443'} == conn_info + assert { + "client_ip": "127.0.0.1", + "client_port": "22", + "server_ip": "10.0.0.1", + "server_port": "443", + } == conn_info - @pytest.mark.parametrize('command, vcs', [ - ('xxx', None), - ('svnserve -t', 'svn'), - ('hg -R repo serve --stdio', 'hg'), - ('git-receive-pack \'repo.git\'', 'git'), - - ]) + @pytest.mark.parametrize( + "command, vcs", + [ + ("xxx", None), + ("svnserve -t", "svn"), + ("hg -R repo serve --stdio", "hg"), + ("git-receive-pack 'repo.git'", "git"), + ], + ) def test_get_repo_details(self, ssh_wrapper, command, vcs): ssh_wrapper.command = command - vcs_type, repo_name, mode = ssh_wrapper.get_repo_details(mode='auto') + vcs_type, repo_name, mode = ssh_wrapper.get_repo_details(mode="auto") assert vcs_type == vcs diff --git a/rhodecode/apps/ssh_support/utils.py b/rhodecode/apps/ssh_support/utils.py index 3d08e951..070588c4 100644 --- a/rhodecode/apps/ssh_support/utils.py +++ b/rhodecode/apps/ssh_support/utils.py @@ -28,72 +28,60 @@ from rhodecode.model.db import true, joinedload, User, UserSshKeys log = logging.getLogger(__name__) -HEADER = \ - "# This file is managed by RhodeCode, please do not edit it manually. # \n" \ +HEADER = ( + "# This file is managed by RhodeCode, please do not edit it manually. # \n" "# Current entries: {}, create date: UTC:{}.\n" +) # Default SSH options for authorized_keys file, can be override via .ini -SSH_OPTS = 'no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding' +SSH_OPTS = "no-pty,no-port-forwarding,no-X11-forwarding,no-agent-forwarding" def get_all_active_keys(): - result = UserSshKeys.query() \ - .join(User) \ - .filter(User != User.get_default_user()) \ - .filter(User.active == true()) \ - .all() + result = UserSshKeys.query().join(User).filter(User != User.get_default_user()).filter(User.active == true()).all() return result -def _generate_ssh_authorized_keys_file( - authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts, debug): +def _generate_ssh_authorized_keys_file(authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts, debug): import rhodecode - authorized_keys_file_path = os.path.abspath( - os.path.expanduser(authorized_keys_file_path)) + authorized_keys_file_path = os.path.abspath(os.path.expanduser(authorized_keys_file_path)) tmp_file_dir = os.path.dirname(authorized_keys_file_path) if not os.path.exists(tmp_file_dir): - log.debug('SSH authorized_keys file dir does not exist, creating one now...') + log.debug("SSH authorized_keys file dir does not exist, creating one now...") os.makedirs(tmp_file_dir) all_active_keys = get_all_active_keys() if allow_shell: - ssh_wrapper_cmd = ssh_wrapper_cmd + ' --shell' + ssh_wrapper_cmd = ssh_wrapper_cmd + " --shell" if debug: - ssh_wrapper_cmd = ssh_wrapper_cmd + ' --debug' + ssh_wrapper_cmd = ssh_wrapper_cmd + " --debug" if not os.path.isfile(authorized_keys_file_path): - log.debug('Creating file at %s', authorized_keys_file_path) - with open(authorized_keys_file_path, 'w'): + log.debug("Creating file at %s", authorized_keys_file_path) + with open(authorized_keys_file_path, "w"): # create a file with write access pass if not os.access(authorized_keys_file_path, os.R_OK): - raise OSError('Access to file {} is without read access'.format( - authorized_keys_file_path)) + raise OSError("Access to file {} is without read access".format(authorized_keys_file_path)) line_tmpl = '{ssh_opts},command="{wrapper_command} {ini_path} --user-id={user_id} --user={user} --key-id={user_key_id}" {key}\n' - fd, tmp_authorized_keys = tempfile.mkstemp( - '.authorized_keys_write_operation', - dir=tmp_file_dir) + fd, tmp_authorized_keys = tempfile.mkstemp(".authorized_keys_write_operation", dir=tmp_file_dir) now = datetime.datetime.utcnow().isoformat() - keys_file = os.fdopen(fd, 'wt') + keys_file = os.fdopen(fd, "wt") keys_file.write(HEADER.format(len(all_active_keys), now)) - ini_path = rhodecode.CONFIG['__file__'] + ini_path = rhodecode.CONFIG["__file__"] for user_key in all_active_keys: username = user_key.user.username user_id = user_key.user.user_id # replace all newline from ends and inside - safe_key_data = user_key.ssh_key_data\ - .strip()\ - .replace('\n', ' ') \ - .replace('\t', ' ') \ - .replace('\r', ' ') + safe_key_data = user_key.ssh_key_data.strip().replace("\n", " ").replace("\t", " ").replace("\r", " ") line = line_tmpl.format( ssh_opts=ssh_opts or SSH_OPTS, @@ -102,10 +90,11 @@ def _generate_ssh_authorized_keys_file( user_id=user_id, user=username, user_key_id=user_key.ssh_key_id, - key=safe_key_data) + key=safe_key_data, + ) keys_file.write(line) - log.debug('addkey: Key added for user: `%s`', username) + log.debug("addkey: Key added for user: `%s`", username) keys_file.close() # Explicitly setting read-only permissions to authorized_keys @@ -115,22 +104,15 @@ def _generate_ssh_authorized_keys_file( def generate_ssh_authorized_keys_file(registry): - log.info('Generating new authorized key file') + log.info("Generating new authorized key file") - authorized_keys_file_path = registry.settings.get( - config_keys.authorized_keys_file_path) + authorized_keys_file_path = registry.settings.get(config_keys.authorized_keys_file_path) - ssh_wrapper_cmd = registry.settings.get( - config_keys.wrapper_cmd) - allow_shell = registry.settings.get( - config_keys.wrapper_allow_shell) - ssh_opts = registry.settings.get( - config_keys.authorized_keys_line_ssh_opts) - debug = registry.settings.get( - config_keys.enable_debug_logging) + ssh_wrapper_cmd = registry.settings.get(config_keys.wrapper_cmd) + allow_shell = registry.settings.get(config_keys.wrapper_allow_shell) + ssh_opts = registry.settings.get(config_keys.authorized_keys_line_ssh_opts) + debug = registry.settings.get(config_keys.enable_debug_logging) - _generate_ssh_authorized_keys_file( - authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts, - debug) + _generate_ssh_authorized_keys_file(authorized_keys_file_path, ssh_wrapper_cmd, allow_shell, ssh_opts, debug) return 0 diff --git a/rhodecode/apps/svn_support/__init__.py b/rhodecode/apps/svn_support/__init__.py index 8f3d20fc..2ff6554d 100644 --- a/rhodecode/apps/svn_support/__init__.py +++ b/rhodecode/apps/svn_support/__init__.py @@ -37,13 +37,13 @@ def _sanitize_settings_and_apply_defaults(settings): Set defaults, convert to python types and validate settings. """ settings_maker = SettingsMaker(settings) - settings_maker.make_setting(config_keys.generate_config, False, parser='bool') - settings_maker.make_setting(config_keys.list_parent_path, True, parser='bool') - settings_maker.make_setting(config_keys.reload_timeout, 10, parser='bool') - settings_maker.make_setting(config_keys.config_file_path, '') - settings_maker.make_setting(config_keys.location_root, '/') - settings_maker.make_setting(config_keys.reload_command, '') - settings_maker.make_setting(config_keys.template, '') + settings_maker.make_setting(config_keys.generate_config, False, parser="bool") + settings_maker.make_setting(config_keys.list_parent_path, True, parser="bool") + settings_maker.make_setting(config_keys.reload_timeout, 10, parser="bool") + settings_maker.make_setting(config_keys.config_file_path, "") + settings_maker.make_setting(config_keys.location_root, "/") + settings_maker.make_setting(config_keys.reload_command, "") + settings_maker.make_setting(config_keys.template, "") settings_maker.env_expand() @@ -52,8 +52,7 @@ def _sanitize_settings_and_apply_defaults(settings): settings[config_keys.reload_timeout] = 0 # Append path separator to location root. - settings[config_keys.location_root] = _append_path_sep( - settings[config_keys.location_root]) + settings[config_keys.location_root] = _append_path_sep(settings[config_keys.location_root]) # Validate settings. if settings[config_keys.generate_config]: @@ -83,6 +82,5 @@ def includeme(config): reload_cmd = settings[config_keys.reload_command] if reload_cmd: reload_timeout = settings[config_keys.reload_timeout] or None - reload_subscriber = AsyncSubprocessSubscriber( - cmd=reload_cmd, timeout=reload_timeout) + reload_subscriber = AsyncSubprocessSubscriber(cmd=reload_cmd, timeout=reload_timeout) config.add_subscriber(reload_subscriber, ModDavSvnConfigChange) diff --git a/rhodecode/apps/svn_support/config_keys.py b/rhodecode/apps/svn_support/config_keys.py index d7003991..99b905fa 100644 --- a/rhodecode/apps/svn_support/config_keys.py +++ b/rhodecode/apps/svn_support/config_keys.py @@ -19,10 +19,10 @@ # Definition of setting keys used to configure this module. Defined here to # avoid repetition of keys throughout the module. -config_file_path = 'svn.proxy.config_file_path' -generate_config = 'svn.proxy.generate_config' -list_parent_path = 'svn.proxy.list_parent_path' -location_root = 'svn.proxy.location_root' -reload_command = 'svn.proxy.reload_cmd' -reload_timeout = 'svn.proxy.reload_timeout' -template = 'svn.proxy.config_template' +config_file_path = "svn.proxy.config_file_path" +generate_config = "svn.proxy.generate_config" +list_parent_path = "svn.proxy.list_parent_path" +location_root = "svn.proxy.location_root" +reload_command = "svn.proxy.reload_cmd" +reload_timeout = "svn.proxy.reload_timeout" +template = "svn.proxy.config_template" diff --git a/rhodecode/apps/svn_support/events.py b/rhodecode/apps/svn_support/events.py index 2185d100..cd1b826c 100644 --- a/rhodecode/apps/svn_support/events.py +++ b/rhodecode/apps/svn_support/events.py @@ -26,5 +26,6 @@ class ModDavSvnConfigChange(RhodecodeEvent): This event will be triggered on every change of the mod dav svn configuration. """ - name = 'mod-dav-svn-config-change' - display_name = _('Configuration for Apache mad_dav_svn changed.') + + name = "mod-dav-svn-config-change" + display_name = _("Configuration for Apache mad_dav_svn changed.") diff --git a/rhodecode/apps/svn_support/subscribers.py b/rhodecode/apps/svn_support/subscribers.py index 5afef5b0..4d0ef4de 100644 --- a/rhodecode/apps/svn_support/subscribers.py +++ b/rhodecode/apps/svn_support/subscribers.py @@ -34,5 +34,4 @@ def generate_config_subscriber(event): try: generate_mod_dav_svn_config(event.request.registry) except Exception: - log.exception( - 'Exception while generating subversion mod_dav_svn configuration.') + log.exception("Exception while generating subversion mod_dav_svn configuration.") diff --git a/rhodecode/apps/svn_support/tests/test_mod_dav_svn_config.py b/rhodecode/apps/svn_support/tests/test_mod_dav_svn_config.py index f93b0079..912381b7 100644 --- a/rhodecode/apps/svn_support/tests/test_mod_dav_svn_config.py +++ b/rhodecode/apps/svn_support/tests/test_mod_dav_svn_config.py @@ -24,34 +24,31 @@ import pytest from rhodecode.apps.svn_support import utils -@pytest.mark.usefixtures('config_stub') +@pytest.mark.usefixtures("config_stub") class TestModDavSvnConfig(object): - @classmethod def setup_class(cls): - cls.location_root = '/location/root/çµäö' - cls.parent_path_root = '/parent/path/çµäö' - cls.realm = 'Dummy Realm (äöüçµ)' + cls.location_root = "/location/root/çµäö" + cls.parent_path_root = "/parent/path/çµäö" + cls.realm = "Dummy Realm (äöüçµ)" @classmethod def get_repo_group_mocks(cls, count=1): repo_groups = [] for num in range(0, count): - full_path = f'/path/to/RepöGröúp-°µ {num}' + full_path = f"/path/to/RepöGröúp-°µ {num}" repo_group_mock = mock.MagicMock() repo_group_mock.full_path = full_path - repo_group_mock.full_path_splitted = full_path.split('/') + repo_group_mock.full_path_splitted = full_path.split("/") repo_groups.append(repo_group_mock) return repo_groups def assert_root_location_directive(self, config): - pattern = ''.format( - location=self.location_root) + pattern = ''.format(location=self.location_root) assert len(re.findall(pattern, config)) == 1 def assert_group_location_directive(self, config, group_path): - pattern = ''.format( - location=self.location_root, group_path=group_path) + pattern = ''.format(location=self.location_root, group_path=group_path) assert len(re.findall(pattern, config)) == 1 def test_render_mod_dav_svn_config(self): @@ -63,21 +60,20 @@ class TestModDavSvnConfig(object): repo_groups=repo_groups, realm=self.realm, use_ssl=True, - template='' + template="", ) # Assert that one location directive exists for each repository group. for group in repo_groups: - self.assert_group_location_directive( - generated_config, group.full_path) + self.assert_group_location_directive(generated_config, group.full_path) # Assert that the root location directive exists. self.assert_root_location_directive(generated_config) def test_render_mod_dav_svn_config_with_alternative_template(self, tmpdir): repo_groups = self.get_repo_group_mocks(count=10) - test_file_path = os.path.join(str(tmpdir), 'example.mako') - with open(test_file_path, 'w') as f: - f.write('TEST_EXAMPLE\n') + test_file_path = os.path.join(str(tmpdir), "example.mako") + with open(test_file_path, "w") as f: + f.write("TEST_EXAMPLE\n") generated_config = utils._render_mod_dav_svn_config( parent_path_root=self.parent_path_root, @@ -86,12 +82,12 @@ class TestModDavSvnConfig(object): repo_groups=repo_groups, realm=self.realm, use_ssl=True, - template=test_file_path + template=test_file_path, ) - assert 'TEST_EXAMPLE' in generated_config + assert "TEST_EXAMPLE" in generated_config - @pytest.mark.parametrize('list_parent_path', [True, False]) - @pytest.mark.parametrize('use_ssl', [True, False]) + @pytest.mark.parametrize("list_parent_path", [True, False]) + @pytest.mark.parametrize("use_ssl", [True, False]) def test_list_parent_path(self, list_parent_path, use_ssl): generated_config = utils._render_mod_dav_svn_config( parent_path_root=self.parent_path_root, @@ -100,20 +96,18 @@ class TestModDavSvnConfig(object): repo_groups=self.get_repo_group_mocks(count=10), realm=self.realm, use_ssl=use_ssl, - template='' + template="", ) # Assert that correct configuration directive is present. if list_parent_path: - assert not re.search(r'SVNListParentPath\s+Off', generated_config) - assert re.search(r'SVNListParentPath\s+On', generated_config) + assert not re.search(r"SVNListParentPath\s+Off", generated_config) + assert re.search(r"SVNListParentPath\s+On", generated_config) else: - assert re.search(r'SVNListParentPath\s+Off', generated_config) - assert not re.search(r'SVNListParentPath\s+On', generated_config) + assert re.search(r"SVNListParentPath\s+Off", generated_config) + assert not re.search(r"SVNListParentPath\s+On", generated_config) if use_ssl: - assert 'RequestHeader edit Destination ^https: http: early' \ - in generated_config + assert "RequestHeader edit Destination ^https: http: early" in generated_config else: - assert 'RequestHeader edit Destination ^https: http: early' \ - in generated_config + assert "RequestHeader edit Destination ^https: http: early" in generated_config diff --git a/rhodecode/apps/svn_support/utils.py b/rhodecode/apps/svn_support/utils.py index ee15fe9e..e6f1432f 100644 --- a/rhodecode/apps/svn_support/utils.py +++ b/rhodecode/apps/svn_support/utils.py @@ -34,7 +34,7 @@ log = logging.getLogger(__name__) def write_mod_dav_svn_config(settings): - use_ssl = str2bool(settings['force_https']) + use_ssl = str2bool(settings["force_https"]) file_path = settings[config_keys.config_file_path] config = _render_mod_dav_svn_config( use_ssl=use_ssl, @@ -42,7 +42,9 @@ def write_mod_dav_svn_config(settings): list_parent_path=settings[config_keys.list_parent_path], location_root=settings[config_keys.location_root], repo_groups=RepoGroup.get_all_repo_groups(), - realm=get_rhodecode_realm(), template=settings[config_keys.template]) + realm=get_rhodecode_realm(), + template=settings[config_keys.template], + ) _write_mod_dav_svn_config(config, file_path) return file_path @@ -63,8 +65,8 @@ def generate_mod_dav_svn_config(registry): def _render_mod_dav_svn_config( - parent_path_root, list_parent_path, location_root, repo_groups, realm, - use_ssl, template): + parent_path_root, list_parent_path, location_root, repo_groups, realm, use_ssl, template +): """ Render mod_dav_svn configuration to string. """ @@ -76,15 +78,14 @@ def _render_mod_dav_svn_config( repo_group_paths.append((location, parent_path)) context = { - 'location_root': location_root, - 'parent_path_root': parent_path_root, - 'repo_group_paths': repo_group_paths, - 'svn_list_parent_path': list_parent_path, - 'rhodecode_realm': realm, - 'use_https': use_ssl, + "location_root": location_root, + "parent_path_root": parent_path_root, + "repo_group_paths": repo_group_paths, + "svn_list_parent_path": list_parent_path, + "rhodecode_realm": realm, + "use_https": use_ssl, } - template = template or \ - 'rhodecode:apps/svn_support/templates/mod-dav-svn.conf.mako' + template = template or "rhodecode:apps/svn_support/templates/mod-dav-svn.conf.mako" # Render the configuration template to string. return render(template, context) @@ -93,5 +94,5 @@ def _write_mod_dav_svn_config(config, filepath): """ Write mod_dav_svn config to file. """ - with codecs.open(filepath, 'w', encoding='utf-8') as f: + with codecs.open(filepath, "w", encoding="utf-8") as f: f.write(config) diff --git a/rhodecode/apps/user_group/__init__.py b/rhodecode/apps/user_group/__init__.py index 2818fece..58bed080 100644 --- a/rhodecode/apps/user_group/__init__.py +++ b/rhodecode/apps/user_group/__init__.py @@ -26,128 +26,155 @@ def admin_routes(config): from rhodecode.apps.user_group.views import UserGroupsView config.add_route( - name='user_group_members_data', - pattern=r'/user_groups/{user_group_id:\d+}/members', - user_group_route=True) + name="user_group_members_data", pattern=r"/user_groups/{user_group_id:\d+}/members", user_group_route=True + ) config.add_view( UserGroupsView, - attr='user_group_members', - route_name='user_group_members_data', request_method='GET', - renderer='json_ext', xhr=True) + attr="user_group_members", + route_name="user_group_members_data", + request_method="GET", + renderer="json_ext", + xhr=True, + ) # user groups perms config.add_route( - name='edit_user_group_perms_summary', - pattern=r'/user_groups/{user_group_id:\d+}/edit/permissions_summary', - user_group_route=True) + name="edit_user_group_perms_summary", + pattern=r"/user_groups/{user_group_id:\d+}/edit/permissions_summary", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_perms_summary', - route_name='edit_user_group_perms_summary', request_method='GET', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_perms_summary", + route_name="edit_user_group_perms_summary", + request_method="GET", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) config.add_route( - name='edit_user_group_perms_summary_json', - pattern=r'/user_groups/{user_group_id:\d+}/edit/permissions_summary/json', - user_group_route=True) + name="edit_user_group_perms_summary_json", + pattern=r"/user_groups/{user_group_id:\d+}/edit/permissions_summary/json", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_perms_summary_json', - route_name='edit_user_group_perms_summary_json', request_method='GET', - renderer='json_ext') + attr="user_group_perms_summary_json", + route_name="edit_user_group_perms_summary_json", + request_method="GET", + renderer="json_ext", + ) # user groups edit - config.add_route( - name='edit_user_group', - pattern=r'/user_groups/{user_group_id:\d+}/edit', - user_group_route=True) + config.add_route(name="edit_user_group", pattern=r"/user_groups/{user_group_id:\d+}/edit", user_group_route=True) config.add_view( UserGroupsView, - attr='user_group_edit', - route_name='edit_user_group', request_method='GET', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_edit", + route_name="edit_user_group", + request_method="GET", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) # user groups update config.add_route( - name='user_groups_update', - pattern=r'/user_groups/{user_group_id:\d+}/update', - user_group_route=True) + name="user_groups_update", pattern=r"/user_groups/{user_group_id:\d+}/update", user_group_route=True + ) config.add_view( UserGroupsView, - attr='user_group_update', - route_name='user_groups_update', request_method='POST', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_update", + route_name="user_groups_update", + request_method="POST", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) config.add_route( - name='edit_user_group_global_perms', - pattern=r'/user_groups/{user_group_id:\d+}/edit/global_permissions', - user_group_route=True) + name="edit_user_group_global_perms", + pattern=r"/user_groups/{user_group_id:\d+}/edit/global_permissions", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_global_perms_edit', - route_name='edit_user_group_global_perms', request_method='GET', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_global_perms_edit", + route_name="edit_user_group_global_perms", + request_method="GET", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) config.add_route( - name='edit_user_group_global_perms_update', - pattern=r'/user_groups/{user_group_id:\d+}/edit/global_permissions/update', - user_group_route=True) + name="edit_user_group_global_perms_update", + pattern=r"/user_groups/{user_group_id:\d+}/edit/global_permissions/update", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_global_perms_update', - route_name='edit_user_group_global_perms_update', request_method='POST', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_global_perms_update", + route_name="edit_user_group_global_perms_update", + request_method="POST", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) config.add_route( - name='edit_user_group_perms', - pattern=r'/user_groups/{user_group_id:\d+}/edit/permissions', - user_group_route=True) + name="edit_user_group_perms", + pattern=r"/user_groups/{user_group_id:\d+}/edit/permissions", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_edit_perms', - route_name='edit_user_group_perms', request_method='GET', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_edit_perms", + route_name="edit_user_group_perms", + request_method="GET", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) config.add_route( - name='edit_user_group_perms_update', - pattern=r'/user_groups/{user_group_id:\d+}/edit/permissions/update', - user_group_route=True) + name="edit_user_group_perms_update", + pattern=r"/user_groups/{user_group_id:\d+}/edit/permissions/update", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_update_perms', - route_name='edit_user_group_perms_update', request_method='POST', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_update_perms", + route_name="edit_user_group_perms_update", + request_method="POST", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) config.add_route( - name='edit_user_group_advanced', - pattern=r'/user_groups/{user_group_id:\d+}/edit/advanced', - user_group_route=True) + name="edit_user_group_advanced", + pattern=r"/user_groups/{user_group_id:\d+}/edit/advanced", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_edit_advanced', - route_name='edit_user_group_advanced', request_method='GET', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_edit_advanced", + route_name="edit_user_group_advanced", + request_method="GET", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) config.add_route( - name='edit_user_group_advanced_sync', - pattern=r'/user_groups/{user_group_id:\d+}/edit/advanced/sync', - user_group_route=True) + name="edit_user_group_advanced_sync", + pattern=r"/user_groups/{user_group_id:\d+}/edit/advanced/sync", + user_group_route=True, + ) config.add_view( UserGroupsView, - attr='user_group_edit_advanced_set_synchronization', - route_name='edit_user_group_advanced_sync', request_method='POST', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_edit_advanced_set_synchronization", + route_name="edit_user_group_advanced_sync", + request_method="POST", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) # user groups delete config.add_route( - name='user_groups_delete', - pattern=r'/user_groups/{user_group_id:\d+}/delete', - user_group_route=True) + name="user_groups_delete", pattern=r"/user_groups/{user_group_id:\d+}/delete", user_group_route=True + ) config.add_view( UserGroupsView, - attr='user_group_delete', - route_name='user_groups_delete', request_method='POST', - renderer='rhodecode:templates/admin/user_groups/user_group_edit.mako') + attr="user_group_delete", + route_name="user_groups_delete", + request_method="POST", + renderer="rhodecode:templates/admin/user_groups/user_group_edit.mako", + ) def includeme(config): diff --git a/rhodecode/apps/user_group/tests/test_user_groups.py b/rhodecode/apps/user_group/tests/test_user_groups.py index f1528c3b..9fc25fa6 100644 --- a/rhodecode/apps/user_group/tests/test_user_groups.py +++ b/rhodecode/apps/user_group/tests/test_user_groups.py @@ -18,8 +18,7 @@ import pytest -from rhodecode.tests import ( - TestController, assert_session_flash, TEST_USER_ADMIN_LOGIN) +from rhodecode.tests import TestController, assert_session_flash, TEST_USER_ADMIN_LOGIN from rhodecode.model.db import UserGroup from rhodecode.model.meta import Session from rhodecode.tests.fixtures.rc_fixture import Fixture @@ -29,65 +28,98 @@ fixture = Fixture() class TestUserGroupsView(TestController): - def test_set_synchronization(self, user_util): self.log_user() user_group_name = user_util.create_user_group().users_group_name - group = Session().query(UserGroup).filter( - UserGroup.users_group_name == user_group_name).one() + group = Session().query(UserGroup).filter(UserGroup.users_group_name == user_group_name).one() - assert group.group_data.get('extern_type') is None + assert group.group_data.get("extern_type") is None # enable self.app.post( - route_path('edit_user_group_advanced_sync', - user_group_id=group.users_group_id), - params={'csrf_token': self.csrf_token}, status=302) + route_path("edit_user_group_advanced_sync", user_group_id=group.users_group_id), + params={"csrf_token": self.csrf_token}, + status=302, + ) - group = Session().query(UserGroup).filter( - UserGroup.users_group_name == user_group_name).one() - assert group.group_data.get('extern_type') == 'manual' - assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN + group = Session().query(UserGroup).filter(UserGroup.users_group_name == user_group_name).one() + assert group.group_data.get("extern_type") == "manual" + assert group.group_data.get("extern_type_set_by") == TEST_USER_ADMIN_LOGIN # disable self.app.post( - route_path('edit_user_group_advanced_sync', - user_group_id=group.users_group_id), - params={'csrf_token': self.csrf_token}, status=302) + route_path("edit_user_group_advanced_sync", user_group_id=group.users_group_id), + params={"csrf_token": self.csrf_token}, + status=302, + ) - group = Session().query(UserGroup).filter( - UserGroup.users_group_name == user_group_name).one() - assert group.group_data.get('extern_type') is None - assert group.group_data.get('extern_type_set_by') == TEST_USER_ADMIN_LOGIN + group = Session().query(UserGroup).filter(UserGroup.users_group_name == user_group_name).one() + assert group.group_data.get("extern_type") is None + assert group.group_data.get("extern_type_set_by") == TEST_USER_ADMIN_LOGIN def test_delete_user_group(self, user_util): self.log_user() user_group_id = user_util.create_user_group().users_group_id - group = Session().query(UserGroup).filter( - UserGroup.users_group_id == user_group_id).one() + group = Session().query(UserGroup).filter(UserGroup.users_group_id == user_group_id).one() self.app.post( - route_path('user_groups_delete', user_group_id=group.users_group_id), - params={'csrf_token': self.csrf_token}) + route_path("user_groups_delete", user_group_id=group.users_group_id), params={"csrf_token": self.csrf_token} + ) - group = Session().query(UserGroup).filter( - UserGroup.users_group_id == user_group_id).scalar() + group = Session().query(UserGroup).filter(UserGroup.users_group_id == user_group_id).scalar() assert group is None - @pytest.mark.parametrize('repo_create, repo_create_write, user_group_create, repo_group_create, fork_create, inherit_default_permissions, expect_error, expect_form_error', [ - ('hg.create.none', 'hg.create.write_on_repogroup.false', 'hg.usergroup.create.false', 'hg.repogroup.create.false', 'hg.fork.none', 'hg.inherit_default_perms.false', False, False), - ('hg.create.repository', 'hg.create.write_on_repogroup.true', 'hg.usergroup.create.true', 'hg.repogroup.create.true', 'hg.fork.repository', 'hg.inherit_default_perms.false', False, False), - ('hg.create.XXX', 'hg.create.write_on_repogroup.true', 'hg.usergroup.create.true', 'hg.repogroup.create.true', 'hg.fork.repository', 'hg.inherit_default_perms.false', False, True), - ('', '', '', '', '', '', True, False), - ]) + @pytest.mark.parametrize( + "repo_create, repo_create_write, user_group_create, repo_group_create, fork_create, inherit_default_permissions, expect_error, expect_form_error", + [ + ( + "hg.create.none", + "hg.create.write_on_repogroup.false", + "hg.usergroup.create.false", + "hg.repogroup.create.false", + "hg.fork.none", + "hg.inherit_default_perms.false", + False, + False, + ), + ( + "hg.create.repository", + "hg.create.write_on_repogroup.true", + "hg.usergroup.create.true", + "hg.repogroup.create.true", + "hg.fork.repository", + "hg.inherit_default_perms.false", + False, + False, + ), + ( + "hg.create.XXX", + "hg.create.write_on_repogroup.true", + "hg.usergroup.create.true", + "hg.repogroup.create.true", + "hg.fork.repository", + "hg.inherit_default_perms.false", + False, + True, + ), + ("", "", "", "", "", "", True, False), + ], + ) def test_global_permissions_on_user_group( - self, repo_create, repo_create_write, user_group_create, - repo_group_create, fork_create, expect_error, expect_form_error, - inherit_default_permissions, user_util): - + self, + repo_create, + repo_create_write, + user_group_create, + repo_group_create, + fork_create, + expect_error, + expect_form_error, + inherit_default_permissions, + user_util, + ): self.log_user() user_group = user_util.create_user_group() @@ -96,32 +128,30 @@ class TestUserGroupsView(TestController): # ENABLE REPO CREATE ON A GROUP perm_params = { - 'inherit_default_permissions': False, - 'default_repo_create': repo_create, - 'default_repo_create_on_write': repo_create_write, - 'default_user_group_create': user_group_create, - 'default_repo_group_create': repo_group_create, - 'default_fork_create': fork_create, - 'default_inherit_default_permissions': inherit_default_permissions, - - 'csrf_token': self.csrf_token, + "inherit_default_permissions": False, + "default_repo_create": repo_create, + "default_repo_create_on_write": repo_create_write, + "default_user_group_create": user_group_create, + "default_repo_group_create": repo_group_create, + "default_fork_create": fork_create, + "default_inherit_default_permissions": inherit_default_permissions, + "csrf_token": self.csrf_token, } response = self.app.post( - route_path('edit_user_group_global_perms_update', - user_group_id=user_group_id), - params=perm_params) + route_path("edit_user_group_global_perms_update", user_group_id=user_group_id), params=perm_params + ) if expect_form_error: assert response.status_int == 200 - response.mustcontain('Value must be one of') + response.mustcontain("Value must be one of") else: if expect_error: - msg = 'An error occurred during permissions saving' + msg = "An error occurred during permissions saving" else: - msg = 'User Group global permissions updated successfully' + msg = "User Group global permissions updated successfully" ug = UserGroup.get_by_group_name(user_group_name) - del perm_params['csrf_token'] - del perm_params['inherit_default_permissions'] + del perm_params["csrf_token"] + del perm_params["inherit_default_permissions"] assert perm_params == ug.get_default_perms() assert_session_flash(response, msg) @@ -129,43 +159,36 @@ class TestUserGroupsView(TestController): self.log_user() user_group = user_util.create_user_group() - self.app.get( - route_path('edit_user_group', - user_group_id=user_group.users_group_id), - status=200) + self.app.get(route_path("edit_user_group", user_group_id=user_group.users_group_id), status=200) def test_update_user_group(self, user_util): user = self.log_user() user_group = user_util.create_user_group() users_group_id = user_group.users_group_id - new_name = user_group.users_group_name + '_CHANGE' + new_name = user_group.users_group_name + "_CHANGE" params = [ - ('users_group_active', False), - ('user_group_description', 'DESC'), - ('users_group_name', new_name), - ('user', user['username']), - ('csrf_token', self.csrf_token), - ('__start__', 'user_group_members:sequence'), - ('__start__', 'member:mapping'), - ('member_user_id', user['user_id']), - ('type', 'existing'), - ('__end__', 'member:mapping'), - ('__end__', 'user_group_members:sequence'), + ("users_group_active", False), + ("user_group_description", "DESC"), + ("users_group_name", new_name), + ("user", user["username"]), + ("csrf_token", self.csrf_token), + ("__start__", "user_group_members:sequence"), + ("__start__", "member:mapping"), + ("member_user_id", user["user_id"]), + ("type", "existing"), + ("__end__", "member:mapping"), + ("__end__", "user_group_members:sequence"), ] - self.app.post( - route_path('user_groups_update', - user_group_id=users_group_id), - params=params, - status=302) + self.app.post(route_path("user_groups_update", user_group_id=users_group_id), params=params, status=302) user_group = UserGroup.get(users_group_id) assert user_group assert user_group.users_group_name == new_name - assert user_group.user_group_description == 'DESC' + assert user_group.user_group_description == "DESC" assert user_group.users_group_active is False def test_update_user_group_name_conflicts(self, user_util): @@ -177,54 +200,50 @@ class TestUserGroupsView(TestController): params = dict( users_group_active=False, - user_group_description='DESC', + user_group_description="DESC", users_group_name=new_name, - csrf_token=self.csrf_token) + csrf_token=self.csrf_token, + ) response = self.app.post( - route_path('user_groups_update', - user_group_id=user_group.users_group_id), - params=params, - status=200) + route_path("user_groups_update", user_group_id=user_group.users_group_id), params=params, status=200 + ) - response.mustcontain('User group `{}` already exists'.format( - new_name)) + response.mustcontain("User group `{}` already exists".format(new_name)) def test_update_members_from_user_ids(self, user_regular): uid = user_regular.user_id username = user_regular.username self.log_user() - user_group = fixture.create_user_group('test_gr_ids') + user_group = fixture.create_user_group("test_gr_ids") assert user_group.members == [] assert user_group.user != user_regular expected_active_state = not user_group.users_group_active form_data = [ - ('csrf_token', self.csrf_token), - ('user', username), - ('users_group_name', 'changed_name'), - ('users_group_active', expected_active_state), - ('user_group_description', 'changed_description'), - - ('__start__', 'user_group_members:sequence'), - ('__start__', 'member:mapping'), - ('member_user_id', uid), - ('type', 'existing'), - ('__end__', 'member:mapping'), - ('__end__', 'user_group_members:sequence'), + ("csrf_token", self.csrf_token), + ("user", username), + ("users_group_name", "changed_name"), + ("users_group_active", expected_active_state), + ("user_group_description", "changed_description"), + ("__start__", "user_group_members:sequence"), + ("__start__", "member:mapping"), + ("member_user_id", uid), + ("type", "existing"), + ("__end__", "member:mapping"), + ("__end__", "user_group_members:sequence"), ] ugid = user_group.users_group_id - self.app.post( - route_path('user_groups_update', user_group_id=ugid), form_data) + self.app.post(route_path("user_groups_update", user_group_id=ugid), form_data) user_group = UserGroup.get(ugid) assert user_group assert user_group.members[0].user_id == uid assert user_group.user_id == uid - assert 'changed_name' in user_group.users_group_name - assert 'changed_description' in user_group.user_group_description + assert "changed_name" in user_group.users_group_name + assert "changed_description" in user_group.user_group_description assert user_group.users_group_active == expected_active_state fixture.destroy_user_group(user_group) diff --git a/rhodecode/apps/user_group/tests/test_user_groups_permissions.py b/rhodecode/apps/user_group/tests/test_user_groups_permissions.py index 66b24b8d..164c0e8c 100644 --- a/rhodecode/apps/user_group/tests/test_user_groups_permissions.py +++ b/rhodecode/apps/user_group/tests/test_user_groups_permissions.py @@ -24,12 +24,9 @@ from rhodecode.tests.routes import route_path @pytest.mark.usefixtures("app") class TestUserGroupPermissionsView(object): - def test_edit_perms_view(self, user_util, autologin_user): user_group = user_util.create_user_group() - self.app.get( - route_path('edit_user_group_perms', - user_group_id=user_group.users_group_id), status=200) + self.app.get(route_path("edit_user_group_perms", user_group_id=user_group.users_group_id), status=200) def test_update_permissions(self, csrf_token, user_util): user_group = user_util.create_user_group() @@ -40,24 +37,20 @@ class TestUserGroupPermissionsView(object): # grant new form_data = permission_update_data_generator( - csrf_token, - default='usergroup.write', - grant=[(user_id, 'usergroup.write', username, 'user')]) + csrf_token, default="usergroup.write", grant=[(user_id, "usergroup.write", username, "user")] + ) response = self.app.post( - route_path('edit_user_group_perms_update', - user_group_id=user_group_id), form_data).follow() + route_path("edit_user_group_perms_update", user_group_id=user_group_id), form_data + ).follow() - assert 'User Group permissions updated' in response + assert "User Group permissions updated" in response # revoke given - form_data = permission_update_data_generator( - csrf_token, - default='usergroup.read', - revoke=[(user_id, 'user')]) + form_data = permission_update_data_generator(csrf_token, default="usergroup.read", revoke=[(user_id, "user")]) response = self.app.post( - route_path('edit_user_group_perms_update', - user_group_id=user_group_id), form_data).follow() + route_path("edit_user_group_perms_update", user_group_id=user_group_id), form_data + ).follow() - assert 'User Group permissions updated' in response + assert "User Group permissions updated" in response diff --git a/rhodecode/apps/user_group/views/__init__.py b/rhodecode/apps/user_group/views/__init__.py index b0139029..92851802 100644 --- a/rhodecode/apps/user_group/views/__init__.py +++ b/rhodecode/apps/user_group/views/__init__.py @@ -27,16 +27,12 @@ from pyramid.response import Response from pyramid.renderers import render from rhodecode import events -from rhodecode.lib.exceptions import ( - RepoGroupAssignmentError, UserGroupAssignedException) -from rhodecode.model.forms import ( - UserGroupPermsForm, UserGroupForm, UserIndividualPermissionsForm, - UserPermissionsForm) +from rhodecode.lib.exceptions import RepoGroupAssignmentError, UserGroupAssignedException +from rhodecode.model.forms import UserGroupPermsForm, UserGroupForm, UserIndividualPermissionsForm, UserPermissionsForm from rhodecode.model.permission import PermissionModel from rhodecode.apps._base import UserGroupAppView -from rhodecode.lib.auth import ( - LoginRequired, HasUserGroupPermissionAnyDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasUserGroupPermissionAnyDecorator, CSRFRequired from rhodecode.lib import helpers as h, audit_logger from rhodecode.lib.utils2 import str2bool, safe_int from rhodecode.model.db import User, UserGroup @@ -47,78 +43,74 @@ log = logging.getLogger(__name__) class UserGroupsView(UserGroupAppView): - def load_default_context(self): c = self._get_local_tmpl_context() - PermissionModel().set_global_permission_choices( - c, gettext_translator=self.request.translate) + PermissionModel().set_global_permission_choices(c, gettext_translator=self.request.translate) return c @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") def user_group_members(self): """ Return members of given user group """ self.load_default_context() user_group = self.db_user_group - group_members_obj = sorted((x.user for x in user_group.members), - key=lambda u: u.username.lower()) + group_members_obj = sorted((x.user for x in user_group.members), key=lambda u: u.username.lower()) group_members = [ { - 'id': user.user_id, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'username': user.username, - 'icon_link': h.gravatar_url(user.email, 30, request=self.request), - 'value_display': h.person(user.email), - 'value': user.username, - 'value_type': 'user', - 'active': user.active, + "id": user.user_id, + "first_name": user.first_name, + "last_name": user.last_name, + "username": user.username, + "icon_link": h.gravatar_url(user.email, 30, request=self.request), + "value_display": h.person(user.email), + "value": user.username, + "value_type": "user", + "active": user.active, } for user in group_members_obj ] - return { - 'members': group_members - } + return {"members": group_members} @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") def user_group_perms_summary(self): c = self.load_default_context() c.user_group = self.db_user_group - c.active = 'perms_summary' - c.permissions = UserGroupModel().get_perms_summary( - c.user_group.users_group_id) + c.active = "perms_summary" + c.permissions = UserGroupModel().get_perms_summary(c.user_group.users_group_id) return self._get_template_context(c) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") def user_group_perms_summary_json(self): self.load_default_context() user_group = self.db_user_group return UserGroupModel().get_perms_summary(user_group.users_group_id) def _revoke_perms_on_yourself(self, form_result): - _updates = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), - form_result['perm_updates']) - _additions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), - form_result['perm_additions']) - _deletions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), - form_result['perm_deletions']) - admin_perm = 'usergroup.admin' - if _updates and _updates[0][1] != admin_perm or \ - _additions and _additions[0][1] != admin_perm or \ - _deletions and _deletions[0][1] != admin_perm: + _updates = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), form_result["perm_updates"]) + _additions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), form_result["perm_additions"]) + _deletions = filter(lambda u: self._rhodecode_user.user_id == int(u[0]), form_result["perm_deletions"]) + admin_perm = "usergroup.admin" + if ( + _updates + and _updates[0][1] != admin_perm + or _additions + and _additions[0][1] != admin_perm + or _deletions + and _deletions[0][1] != admin_perm + ): return True return False @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") @CSRFRequired() def user_group_update(self): _ = self.request.translate @@ -134,45 +126,43 @@ class UserGroupsView(UserGroupAppView): c.group_members_obj = [x.user for x in c.user_group.members] c.group_members_obj.sort(key=lambda u: u.username.lower()) c.group_members = [(x.user_id, x.username) for x in c.group_members_obj] - c.active = 'settings' + c.active = "settings" users_group_form = UserGroupForm( - self.request.translate, edit=True, - old_data=c.user_group.get_dict(), allow_disabled=True)() + self.request.translate, edit=True, old_data=c.user_group.get_dict(), allow_disabled=True + )() old_values = c.user_group.get_api_data() try: form_result = users_group_form.to_python(self.request.POST) pstruct = peppercorn.parse(self.request.POST.items()) - form_result['users_group_members'] = pstruct['user_group_members'] + form_result["users_group_members"] = pstruct["user_group_members"] - user_group, added_members, removed_members = \ - UserGroupModel().update(c.user_group, form_result) - new_user_group_name = form_result['users_group_name'] + user_group, added_members, removed_members = UserGroupModel().update(c.user_group, form_result) + new_user_group_name = form_result["users_group_name"] for user_id in added_members: user = User.get(user_id) user_data = user.get_api_data() audit_logger.store_web( - 'user_group.edit.member.add', - action_data={'user': user_data, 'old_data': old_values}, - user=self._rhodecode_user) + "user_group.edit.member.add", + action_data={"user": user_data, "old_data": old_values}, + user=self._rhodecode_user, + ) for user_id in removed_members: user = User.get(user_id) user_data = user.get_api_data() audit_logger.store_web( - 'user_group.edit.member.delete', - action_data={'user': user_data, 'old_data': old_values}, - user=self._rhodecode_user) + "user_group.edit.member.delete", + action_data={"user": user_data, "old_data": old_values}, + user=self._rhodecode_user, + ) - audit_logger.store_web( - 'user_group.edit', action_data={'old_data': old_values}, - user=self._rhodecode_user) + audit_logger.store_web("user_group.edit", action_data={"old_data": old_values}, user=self._rhodecode_user) - h.flash(_('Updated user group %s') % new_user_group_name, - category='success') + h.flash(_("Updated user group %s") % new_user_group_name, category="success") affected_user_ids = [] for user_id in added_members + removed_members: @@ -180,7 +170,7 @@ class UserGroupsView(UserGroupAppView): name_changed = old_user_group_name != new_user_group_name if name_changed: - owner = User.get_by_username(form_result['user']) + owner = User.get_by_username(form_result["user"]) owner_id = owner.user_id if owner else self._rhodecode_user.user_id affected_user_ids.append(self._rhodecode_user.user_id) affected_user_ids.append(owner_id) @@ -193,54 +183,46 @@ class UserGroupsView(UserGroupAppView): e = errors.error_dict or {} data = render( - 'rhodecode:templates/admin/user_groups/user_group_edit.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/user_groups/user_group_edit.mako", + self._get_template_context(c), + self.request, + ) html = formencode.htmlfill.render( - data, - defaults=defaults, - errors=e, - prefix_error=False, - encoding="UTF-8", - force_defaults=False + data, defaults=defaults, errors=e, prefix_error=False, encoding="UTF-8", force_defaults=False ) return Response(html) except Exception: log.exception("Exception during update of user group") - h.flash(_('Error occurred during update of user group %s') - % new_user_group_name, category='error') + h.flash(_("Error occurred during update of user group %s") % new_user_group_name, category="error") - raise HTTPFound( - h.route_path('edit_user_group', user_group_id=user_group_id)) + raise HTTPFound(h.route_path("edit_user_group", user_group_id=user_group_id)) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") @CSRFRequired() def user_group_delete(self): _ = self.request.translate user_group = self.db_user_group self.load_default_context() - force = str2bool(self.request.POST.get('force')) + force = str2bool(self.request.POST.get("force")) old_values = user_group.get_api_data() try: UserGroupModel().delete(user_group, force=force) - audit_logger.store_web( - 'user.delete', action_data={'old_data': old_values}, - user=self._rhodecode_user) + audit_logger.store_web("user.delete", action_data={"old_data": old_values}, user=self._rhodecode_user) Session().commit() - h.flash(_('Successfully deleted user group'), category='success') + h.flash(_("Successfully deleted user group"), category="success") except UserGroupAssignedException as e: - h.flash(str(e), category='error') + h.flash(str(e), category="error") except Exception: log.exception("Exception during deletion of user group") - h.flash(_('An error occurred during deletion of user group'), - category='error') - raise HTTPFound(h.route_path('user_groups')) + h.flash(_("An error occurred during deletion of user group"), category="error") + raise HTTPFound(h.route_path("user_groups")) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") def user_group_edit(self): user_group = self.db_user_group @@ -250,58 +232,46 @@ class UserGroupsView(UserGroupAppView): c.group_members_obj.sort(key=lambda u: u.username.lower()) c.group_members = [(x.user_id, x.username) for x in c.group_members_obj] - c.active = 'settings' + c.active = "settings" defaults = user_group.get_dict() # fill owner if user_group.user: - defaults.update({'user': user_group.user.username}) + defaults.update({"user": user_group.user.username}) else: replacement_user = User.get_first_super_admin().username - defaults.update({'user': replacement_user}) + defaults.update({"user": replacement_user}) data = render( - 'rhodecode:templates/admin/user_groups/user_group_edit.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + "rhodecode:templates/admin/user_groups/user_group_edit.mako", self._get_template_context(c), self.request ) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") def user_group_edit_perms(self): user_group = self.db_user_group c = self.load_default_context() c.user_group = user_group - c.active = 'perms' + c.active = "perms" defaults = {} # fill user group users for p in c.user_group.user_user_group_to_perm: - defaults.update({'u_perm_%s' % p.user.user_id: - p.permission.permission_name}) + defaults.update({"u_perm_%s" % p.user.user_id: p.permission.permission_name}) for p in c.user_group.user_group_user_group_to_perm: - defaults.update({'g_perm_%s' % p.user_group.users_group_id: - p.permission.permission_name}) + defaults.update({"g_perm_%s" % p.user_group.users_group_id: p.permission.permission_name}) data = render( - 'rhodecode:templates/admin/user_groups/user_group_edit.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + "rhodecode:templates/admin/user_groups/user_group_edit.mako", self._get_template_context(c), self.request ) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") @CSRFRequired() def user_group_update_perms(self): """ @@ -317,77 +287,64 @@ class UserGroupsView(UserGroupAppView): if not self._rhodecode_user.is_admin: if self._revoke_perms_on_yourself(form): - msg = _('Cannot change permission for yourself as admin') - h.flash(msg, category='warning') - raise HTTPFound( - h.route_path('edit_user_group_perms', - user_group_id=user_group_id)) + msg = _("Cannot change permission for yourself as admin") + h.flash(msg, category="warning") + raise HTTPFound(h.route_path("edit_user_group_perms", user_group_id=user_group_id)) try: changes = UserGroupModel().update_permissions( - user_group, - form['perm_additions'], form['perm_updates'], - form['perm_deletions']) + user_group, form["perm_additions"], form["perm_updates"], form["perm_deletions"] + ) except RepoGroupAssignmentError: - h.flash(_('Target group cannot be the same'), category='error') - raise HTTPFound( - h.route_path('edit_user_group_perms', - user_group_id=user_group_id)) + h.flash(_("Target group cannot be the same"), category="error") + raise HTTPFound(h.route_path("edit_user_group_perms", user_group_id=user_group_id)) action_data = { - 'added': changes['added'], - 'updated': changes['updated'], - 'deleted': changes['deleted'], + "added": changes["added"], + "updated": changes["updated"], + "deleted": changes["deleted"], } - audit_logger.store_web( - 'user_group.edit.permissions', action_data=action_data, - user=self._rhodecode_user) + audit_logger.store_web("user_group.edit.permissions", action_data=action_data, user=self._rhodecode_user) Session().commit() - h.flash(_('User Group permissions updated'), category='success') + h.flash(_("User Group permissions updated"), category="success") affected_user_ids = [] - for change in changes['added'] + changes['updated'] + changes['deleted']: - if change['type'] == 'user': - affected_user_ids.append(change['id']) - if change['type'] == 'user_group': - user_group = UserGroup.get(safe_int(change['id'])) + for change in changes["added"] + changes["updated"] + changes["deleted"]: + if change["type"] == "user": + affected_user_ids.append(change["id"]) + if change["type"] == "user_group": + user_group = UserGroup.get(safe_int(change["id"])) if user_group: group_members_ids = [x.user_id for x in user_group.members] affected_user_ids.extend(group_members_ids) PermissionModel().trigger_permission_flush(affected_user_ids) - raise HTTPFound( - h.route_path('edit_user_group_perms', user_group_id=user_group_id)) + raise HTTPFound(h.route_path("edit_user_group_perms", user_group_id=user_group_id)) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") def user_group_global_perms_edit(self): user_group = self.db_user_group c = self.load_default_context() c.user_group = user_group - c.active = 'global_perms' + c.active = "global_perms" c.default_user = User.get_default_user() defaults = c.user_group.get_dict() - defaults.update(c.default_user.get_default_perms(suffix='_inherited')) + defaults.update(c.default_user.get_default_perms(suffix="_inherited")) defaults.update(c.user_group.get_default_perms()) data = render( - 'rhodecode:templates/admin/user_groups/user_group_edit.mako', - self._get_template_context(c), self.request) - html = formencode.htmlfill.render( - data, - defaults=defaults, - encoding="UTF-8", - force_defaults=False + "rhodecode:templates/admin/user_groups/user_group_edit.mako", self._get_template_context(c), self.request ) + html = formencode.htmlfill.render(data, defaults=defaults, encoding="UTF-8", force_defaults=False) return Response(html) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") @CSRFRequired() def user_group_global_perms_update(self): _ = self.request.translate @@ -396,13 +353,13 @@ class UserGroupsView(UserGroupAppView): c = self.load_default_context() c.user_group = user_group - c.active = 'global_perms' + c.active = "global_perms" try: # first stage that verifies the checkbox _form = UserIndividualPermissionsForm(self.request.translate) form_result = _form.to_python(dict(self.request.POST)) - inherit_perms = form_result['inherit_default_permissions'] + inherit_perms = form_result["inherit_default_permissions"] user_group.inherit_default_permissions = inherit_perms Session().add(user_group) @@ -415,98 +372,90 @@ class UserGroupsView(UserGroupAppView): [x[0] for x in c.repo_group_create_choices], [x[0] for x in c.user_group_create_choices], [x[0] for x in c.fork_choices], - [x[0] for x in c.inherit_default_permission_choices])() + [x[0] for x in c.inherit_default_permission_choices], + )() form_result = _form.to_python(dict(self.request.POST)) - form_result.update( - {'perm_user_group_id': user_group.users_group_id}) + form_result.update({"perm_user_group_id": user_group.users_group_id}) PermissionModel().update_user_group_permissions(form_result) Session().commit() - h.flash(_('User Group global permissions updated successfully'), - category='success') + h.flash(_("User Group global permissions updated successfully"), category="success") except formencode.Invalid as errors: defaults = errors.value data = render( - 'rhodecode:templates/admin/user_groups/user_group_edit.mako', - self._get_template_context(c), self.request) + "rhodecode:templates/admin/user_groups/user_group_edit.mako", + self._get_template_context(c), + self.request, + ) html = formencode.htmlfill.render( data, defaults=defaults, errors=errors.error_dict or {}, prefix_error=False, encoding="UTF-8", - force_defaults=False + force_defaults=False, ) return Response(html) except Exception: log.exception("Exception during permissions saving") - h.flash(_('An error occurred during permissions saving'), - category='error') + h.flash(_("An error occurred during permissions saving"), category="error") - raise HTTPFound( - h.route_path('edit_user_group_global_perms', - user_group_id=user_group_id)) + raise HTTPFound(h.route_path("edit_user_group_global_perms", user_group_id=user_group_id)) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") def user_group_edit_advanced(self): user_group = self.db_user_group c = self.load_default_context() c.user_group = user_group - c.active = 'advanced' - c.group_members_obj = sorted( - (x.user for x in c.user_group.members), - key=lambda u: u.username.lower()) + c.active = "advanced" + c.group_members_obj = sorted((x.user for x in c.user_group.members), key=lambda u: u.username.lower()) c.group_to_repos = sorted( - (x.repository for x in c.user_group.users_group_repo_to_perm), - key=lambda u: u.repo_name.lower()) + (x.repository for x in c.user_group.users_group_repo_to_perm), key=lambda u: u.repo_name.lower() + ) c.group_to_repo_groups = sorted( - (x.group for x in c.user_group.users_group_repo_group_to_perm), - key=lambda u: u.group_name.lower()) + (x.group for x in c.user_group.users_group_repo_group_to_perm), key=lambda u: u.group_name.lower() + ) c.group_to_review_rules = sorted( - (x.users_group for x in c.user_group.user_group_review_rules), - key=lambda u: u.users_group_name.lower()) + (x.users_group for x in c.user_group.user_group_review_rules), key=lambda u: u.users_group_name.lower() + ) return self._get_template_context(c) @LoginRequired() - @HasUserGroupPermissionAnyDecorator('usergroup.admin') + @HasUserGroupPermissionAnyDecorator("usergroup.admin") @CSRFRequired() def user_group_edit_advanced_set_synchronization(self): _ = self.request.translate user_group = self.db_user_group user_group_id = user_group.users_group_id - existing = user_group.group_data.get('extern_type') + existing = user_group.group_data.get("extern_type") if existing: new_state = user_group.group_data - new_state['extern_type'] = None + new_state["extern_type"] = None else: new_state = user_group.group_data - new_state['extern_type'] = 'manual' - new_state['extern_type_set_by'] = self._rhodecode_user.username + new_state["extern_type"] = "manual" + new_state["extern_type_set_by"] = self._rhodecode_user.username try: user_group.group_data = new_state Session().add(user_group) Session().commit() - h.flash(_('User Group synchronization updated successfully'), - category='success') + h.flash(_("User Group synchronization updated successfully"), category="success") except Exception: log.exception("Exception during sync settings saving") - h.flash(_('An error occurred during synchronization update'), - category='error') + h.flash(_("An error occurred during synchronization update"), category="error") - raise HTTPFound( - h.route_path('edit_user_group_advanced', - user_group_id=user_group_id)) + raise HTTPFound(h.route_path("edit_user_group_advanced", user_group_id=user_group_id)) diff --git a/rhodecode/apps/user_group_profile/__init__.py b/rhodecode/apps/user_group_profile/__init__.py index 509e2d5e..5b8b4733 100644 --- a/rhodecode/apps/user_group_profile/__init__.py +++ b/rhodecode/apps/user_group_profile/__init__.py @@ -20,11 +20,11 @@ def includeme(config): from rhodecode.apps.user_group_profile.views import UserGroupProfileView - config.add_route( - name='user_group_profile', - pattern='/_profile_user_group/{user_group_name}') + config.add_route(name="user_group_profile", pattern="/_profile_user_group/{user_group_name}") config.add_view( UserGroupProfileView, - attr='user_group_profile', - route_name='user_group_profile', request_method='GET', - renderer='rhodecode:templates/user_group/user_group.mako') + attr="user_group_profile", + route_name="user_group_profile", + request_method="GET", + renderer="rhodecode:templates/user_group/user_group.mako", + ) diff --git a/rhodecode/apps/user_group_profile/tests/test_user_group.py b/rhodecode/apps/user_group_profile/tests/test_user_group.py index 3679b1a2..07782403 100644 --- a/rhodecode/apps/user_group_profile/tests/test_user_group.py +++ b/rhodecode/apps/user_group_profile/tests/test_user_group.py @@ -16,8 +16,7 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ from rhodecode.model.user_group import UserGroupModel -from rhodecode.tests import ( - TestController, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) +from rhodecode.tests import TestController, TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.routes import route_path @@ -25,46 +24,48 @@ fixture = Fixture() class TestUsersController(TestController): - def test_user_group_profile(self, user_util): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) user, usergroup = user_util.create_user_with_group() - response = self.app.get(route_path('profile_user_group', user_group_name=usergroup.users_group_name)) + response = self.app.get(route_path("profile_user_group", user_group_name=usergroup.users_group_name)) response.mustcontain(usergroup.users_group_name) response.mustcontain(user.username) def test_user_can_check_own_group(self, user_util): user = user_util.create_user( - TEST_USER_REGULAR_LOGIN, password=TEST_USER_REGULAR_PASS, email='testme@rhodecode.org') + TEST_USER_REGULAR_LOGIN, password=TEST_USER_REGULAR_PASS, email="testme@rhodecode.org" + ) self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) usergroup = user_util.create_user_group(owner=user) - response = self.app.get(route_path('profile_user_group', user_group_name=usergroup.users_group_name)) + response = self.app.get(route_path("profile_user_group", user_group_name=usergroup.users_group_name)) response.mustcontain(usergroup.users_group_name) response.mustcontain(user.username) def test_user_can_not_check_other_group(self, user_util): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) user_group = user_util.create_user_group() - UserGroupModel().grant_user_permission(user_group, self._get_logged_user(), 'usergroup.none') - response = self.app.get(route_path('profile_user_group', user_group_name=user_group.users_group_name), status=404) + UserGroupModel().grant_user_permission(user_group, self._get_logged_user(), "usergroup.none") + response = self.app.get( + route_path("profile_user_group", user_group_name=user_group.users_group_name), status=404 + ) assert response.status_code == 404 def test_another_user_can_check_if_he_is_in_group(self, user_util): self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - user = user_util.create_user( - 'test-my-user', password='qweqwe', email='testme@rhodecode.org') + user = user_util.create_user("test-my-user", password="qweqwe", email="testme@rhodecode.org") user_group = user_util.create_user_group() UserGroupModel().add_user_to_group(user_group, user) - UserGroupModel().grant_user_permission(user_group, self._get_logged_user(), 'usergroup.read') - response = self.app.get(route_path('profile_user_group', user_group_name=user_group.users_group_name)) + UserGroupModel().grant_user_permission(user_group, self._get_logged_user(), "usergroup.read") + response = self.app.get(route_path("profile_user_group", user_group_name=user_group.users_group_name)) response.mustcontain(user_group.users_group_name) response.mustcontain(user.username) def test_with_anonymous_user(self, user_util): - user = user_util.create_user( - 'test-my-user', password='qweqwe', email='testme@rhodecode.org') + user = user_util.create_user("test-my-user", password="qweqwe", email="testme@rhodecode.org") user_group = user_util.create_user_group() UserGroupModel().add_user_to_group(user_group, user) - response = self.app.get(route_path('profile_user_group', user_group_name=user_group.users_group_name), status=302) - assert response.status_code == 302 \ No newline at end of file + response = self.app.get( + route_path("profile_user_group", user_group_name=user_group.users_group_name), status=302 + ) + assert response.status_code == 302 diff --git a/rhodecode/apps/user_group_profile/views.py b/rhodecode/apps/user_group_profile/views.py index 333ae22e..68f12779 100644 --- a/rhodecode/apps/user_group_profile/views.py +++ b/rhodecode/apps/user_group_profile/views.py @@ -30,19 +30,21 @@ log = logging.getLogger(__name__) class UserGroupProfileView(BaseAppView): - @LoginRequired() @NotAnonymous() - @HasUserGroupPermissionAnyDecorator('usergroup.read', 'usergroup.write', 'usergroup.admin',) + @HasUserGroupPermissionAnyDecorator( + "usergroup.read", + "usergroup.write", + "usergroup.admin", + ) def user_group_profile(self): c = self._get_local_tmpl_context() - c.active = 'profile' - self.db_user_group_name = self.request.matchdict.get('user_group_name') + c.active = "profile" + self.db_user_group_name = self.request.matchdict.get("user_group_name") c.user_group = UserGroup().get_by_group_name(self.db_user_group_name) if not c.user_group: raise HTTPNotFound() - group_members_obj = sorted((x.user for x in c.user_group.members), - key=lambda u: u.username.lower()) + group_members_obj = sorted((x.user for x in c.user_group.members), key=lambda u: u.username.lower()) c.group_members = group_members_obj c.anonymous = self._rhodecode_user.username == User.DEFAULT_USER return self._get_template_context(c) diff --git a/rhodecode/apps/user_profile/__init__.py b/rhodecode/apps/user_profile/__init__.py index e52b1f52..7e6a63e3 100644 --- a/rhodecode/apps/user_profile/__init__.py +++ b/rhodecode/apps/user_profile/__init__.py @@ -20,11 +20,11 @@ def includeme(config): from rhodecode.apps.user_profile.views import UserProfileView - config.add_route( - name='user_profile', - pattern='/_profiles/{username}') + config.add_route(name="user_profile", pattern="/_profiles/{username}") config.add_view( UserProfileView, - attr='user_profile', - route_name='user_profile', request_method='GET', - renderer='rhodecode:templates/users/user.mako') + attr="user_profile", + route_name="user_profile", + request_method="GET", + renderer="rhodecode:templates/users/user.mako", + ) diff --git a/rhodecode/apps/user_profile/tests/test_users.py b/rhodecode/apps/user_profile/tests/test_users.py index c31b0b83..a49b2e81 100644 --- a/rhodecode/apps/user_profile/tests/test_users.py +++ b/rhodecode/apps/user_profile/tests/test_users.py @@ -20,8 +20,12 @@ import pytest from rhodecode.model.db import User from rhodecode.tests import ( - TestController, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, - TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) + TestController, + TEST_USER_ADMIN_LOGIN, + TEST_USER_ADMIN_PASS, + TEST_USER_REGULAR_LOGIN, + TEST_USER_REGULAR_PASS, +) from rhodecode.tests.fixtures.rc_fixture import Fixture from rhodecode.tests.utils import AssertResponse from rhodecode.tests.routes import route_path @@ -30,41 +34,38 @@ fixture = Fixture() class TestUsersController(TestController): - def test_user_profile(self, user_util): - edit_link_css = '.user-profile .panel-edit' + edit_link_css = ".user-profile .panel-edit" self.log_user(TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS) - user = user_util.create_user( - 'test-my-user', password='qweqwe', email='testme@rhodecode.org') + user = user_util.create_user("test-my-user", password="qweqwe", email="testme@rhodecode.org") username = user.username - response = self.app.get(route_path('user_profile', username=username)) - response.mustcontain('testme') - response.mustcontain('testme@rhodecode.org') + response = self.app.get(route_path("user_profile", username=username)) + response.mustcontain("testme") + response.mustcontain("testme@rhodecode.org") assert_response = response.assert_response() assert_response.no_element_exists(edit_link_css) # edit should be available to superadmin users self.logout_user() self.log_user(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) - response = self.app.get(route_path('user_profile', username=username)) + response = self.app.get(route_path("user_profile", username=username)) assert_response = response.assert_response() - assert_response.element_contains(edit_link_css, 'Edit') + assert_response.element_contains(edit_link_css, "Edit") def test_user_profile_not_available(self, user_util): user = user_util.create_user() username = user.username # not logged in, redirect - self.app.get(route_path('user_profile', username=username), status=302) + self.app.get(route_path("user_profile", username=username), status=302) self.log_user() # after log-in show - self.app.get(route_path('user_profile', username=username), status=200) + self.app.get(route_path("user_profile", username=username), status=200) # default user, not allowed to show it - self.app.get( - route_path('user_profile', username=User.DEFAULT_USER), status=404) + self.app.get(route_path("user_profile", username=User.DEFAULT_USER), status=404) # actual 404 - self.app.get(route_path('user_profile', username='unknown'), status=404) + self.app.get(route_path("user_profile", username="unknown"), status=404) diff --git a/rhodecode/apps/user_profile/views.py b/rhodecode/apps/user_profile/views.py index d0d82f9f..bbc1db44 100644 --- a/rhodecode/apps/user_profile/views.py +++ b/rhodecode/apps/user_profile/views.py @@ -30,15 +30,14 @@ log = logging.getLogger(__name__) class UserProfileView(BaseAppView): - @LoginRequired() @NotAnonymous() def user_profile(self): # register local template context c = self._get_local_tmpl_context() - c.active = 'user_profile' + c.active = "user_profile" - username = self.request.matchdict.get('username') + username = self.request.matchdict.get("username") c.user = UserModel().get_by_username(username) if not c.user or c.user.username == User.DEFAULT_USER: diff --git a/rhodecode/authentication/__init__.py b/rhodecode/authentication/__init__.py index 00b46f1c..9d31b427 100644 --- a/rhodecode/authentication/__init__.py +++ b/rhodecode/authentication/__init__.py @@ -29,7 +29,7 @@ from rhodecode.model.settings import SettingsModel log = logging.getLogger(__name__) -legacy_plugin_prefix = 'py:' +legacy_plugin_prefix = "py:" plugin_default_auth_ttl = 30 @@ -46,10 +46,9 @@ def discover_legacy_plugins(config, prefix=legacy_plugin_prefix): used for the legacy plugins. """ - log.debug('authentication: running legacy plugin discovery for prefix %s', - legacy_plugin_prefix) + log.debug("authentication: running legacy plugin discovery for prefix %s", legacy_plugin_prefix) try: - auth_plugins = SettingsModel().get_setting_by_name('auth_plugins') + auth_plugins = SettingsModel().get_setting_by_name("auth_plugins") enabled_plugins = auth_plugins.app_settings_value legacy_plugins = [id_ for id_ in enabled_plugins if id_.startswith(prefix)] except Exception: @@ -61,37 +60,35 @@ def discover_legacy_plugins(config, prefix=legacy_plugin_prefix): plugin = _import_legacy_plugin(plugin_id) config.include(plugin.includeme) except Exception as e: - log.exception( - 'Exception while loading legacy authentication plugin ' - '"%s": %s', plugin_id, e) + log.exception('Exception while loading legacy authentication plugin "%s": %s', plugin_id, e) def includeme(config): - config.set_security_policy(SessionAuthenticationHelper()) # Create authentication plugin registry and add it to the pyramid registry. authn_registry = AuthenticationPluginRegistry(config.get_settings()) - config.add_directive('add_authn_plugin', authn_registry.add_authn_plugin) + config.add_directive("add_authn_plugin", authn_registry.add_authn_plugin) config.registry.registerUtility(authn_registry) # Create authentication traversal root resource. authn_root_resource = root_factory() - config.add_directive('add_authn_resource', - authn_root_resource.add_authn_resource) + config.add_directive("add_authn_resource", authn_root_resource.add_authn_resource) # Add the authentication traversal route. - config.add_route('auth_home', - ADMIN_PREFIX + '/auth*traverse', - factory=root_factory) + config.add_route("auth_home", ADMIN_PREFIX + "/auth*traverse", factory=root_factory) # Add the authentication settings root views. - config.add_view('rhodecode.authentication.views.AuthSettingsView', - attr='index', - request_method='GET', - route_name='auth_home', - context=AuthnRootResource) - config.add_view('rhodecode.authentication.views.AuthSettingsView', - attr='auth_settings', - request_method='POST', - route_name='auth_home', - context=AuthnRootResource) + config.add_view( + "rhodecode.authentication.views.AuthSettingsView", + attr="index", + request_method="GET", + route_name="auth_home", + context=AuthnRootResource, + ) + config.add_view( + "rhodecode.authentication.views.AuthSettingsView", + attr="auth_settings", + request_method="POST", + route_name="auth_home", + context=AuthnRootResource, + ) diff --git a/rhodecode/authentication/base.py b/rhodecode/authentication/base.py index 75f53057..8adebfa8 100644 --- a/rhodecode/authentication/base.py +++ b/rhodecode/authentication/base.py @@ -19,6 +19,7 @@ """ Authentication modules """ + import socket import string import colander @@ -39,7 +40,7 @@ from rhodecode.lib.statsd_client import StatsdClient from rhodecode.lib.auth import PasswordGenerator, _RhodeCodeCryptoBCrypt from rhodecode.lib.str_utils import safe_bytes from rhodecode.lib.utils2 import safe_int, safe_str -from rhodecode.lib.exceptions import (LdapConnectionError, LdapUsernameError, LdapPasswordError) +from rhodecode.lib.exceptions import LdapConnectionError, LdapUsernameError, LdapPasswordError from rhodecode.model.db import User from rhodecode.model.meta import Session from rhodecode.model.settings import SettingsModel @@ -50,16 +51,17 @@ from rhodecode.model.user_group import UserGroupModel log = logging.getLogger(__name__) # auth types that authenticate() function can receive -VCS_TYPE = 'vcs' -HTTP_TYPE = 'http' +VCS_TYPE = "vcs" +HTTP_TYPE = "http" -external_auth_session_key = 'rhodecode.external_auth' +external_auth_session_key = "rhodecode.external_auth" class hybrid_property(object): """ a property decorator that works both for instance and class """ + def __init__(self, fget, fset=None, fdel=None, expr=None): self.fget = fget self.fset = fset @@ -88,6 +90,7 @@ class LazyFormencode(object): def __call__(self, *args, **kwargs): from inspect import isfunction + formencode_obj = self.formencode_obj if isfunction(formencode_obj): # case we wrap validators into functions @@ -111,17 +114,13 @@ class RhodeCodeAuthPluginBase(object): "lastname": "last name", "email": "email address", "groups": '["list", "of", "groups"]', - "user_group_sync": - 'True|False defines if returned user groups should be synced', + "user_group_sync": "True|False defines if returned user groups should be synced", "extern_name": "name in external source of record", "extern_type": "type of external source of record", - "admin": 'True|False defines if user should be RhodeCode super admin', - "active": - 'True|False defines active state of user internally for RhodeCode', - "active_from_extern": - "True|False|None, active state from the external auth, " - "None means use definition from RhodeCode extern_type active value" - + "admin": "True|False defines if user should be RhodeCode super admin", + "active": "True|False defines active state of user internally for RhodeCode", + "active_from_extern": "True|False|None, active state from the external auth, " + "None means use definition from RhodeCode extern_type active value", } # set on authenticate() method and via set_auth_type func. auth_type = None @@ -138,10 +137,10 @@ class RhodeCodeAuthPluginBase(object): # Mapping of python to DB settings model types. Plugins may override or # extend this mapping. _settings_type_map = { - colander.String: 'unicode', - colander.Integer: 'int', - colander.Boolean: 'bool', - colander.List: 'list', + colander.String: "unicode", + colander.Integer: "int", + colander.Boolean: "bool", + colander.List: "list", } # list of keys in settings that are unsafe to be logged, should be passwords @@ -161,7 +160,7 @@ class RhodeCodeAuthPluginBase(object): # TODO: johbo: Using the name here is problematic. It would be good to # introduce either new models in the database to hold Plugin and # PluginSetting or to use the plugin id here. - return f'auth_{self.name}_{name}' + return f"auth_{self.name}_{name}" def _get_setting_type(self, name): """ @@ -171,10 +170,9 @@ class RhodeCodeAuthPluginBase(object): encrypted. """ schema_node = self.get_settings_schema().get(name) - db_type = self._settings_type_map.get( - type(schema_node.typ), 'unicode') + db_type = self._settings_type_map.get(type(schema_node.typ), "unicode") if name in self._settings_encrypted: - db_type = f'{db_type}.encrypted' + db_type = f"{db_type}.encrypted" return db_type @classmethod @@ -182,14 +180,14 @@ class RhodeCodeAuthPluginBase(object): """ Defines documentation url which helps with plugin setup """ - return '' + return "" @classmethod def icon(cls): """ Defines ICON in SVG format for authentication method """ - return '' + return "" def is_enabled(self): """ @@ -205,8 +203,7 @@ class RhodeCodeAuthPluginBase(object): Returns true if the plugin is activated. An activated plugin is consulted during authentication, assumed it is also enabled. """ - return self.get_setting_by_name( - 'enabled', plugin_cached_settings=plugin_cached_settings) + return self.get_setting_by_name("enabled", plugin_cached_settings=plugin_cached_settings) def get_id(self): """ @@ -219,7 +216,7 @@ class RhodeCodeAuthPluginBase(object): Returns a translation string for displaying purposes. if load_from_settings is set, plugin settings can override the display name """ - raise NotImplementedError('Not implemented in base class') + raise NotImplementedError("Not implemented in base class") def get_settings_schema(self): """ @@ -230,8 +227,7 @@ class RhodeCodeAuthPluginBase(object): def _propagate_settings(self, raw_settings): settings = {} for node in self.get_settings_schema(): - settings[node.name] = self.get_setting_by_name( - node.name, plugin_cached_settings=raw_settings) + settings[node.name] = self.get_setting_by_name(node.name, plugin_cached_settings=raw_settings) return settings def get_settings(self, use_cache=True): @@ -248,7 +244,7 @@ class RhodeCodeAuthPluginBase(object): """ Returns a plugin setting by name. """ - full_name = f'rhodecode_{self._get_setting_full_name(name)}' + full_name = f"rhodecode_{self._get_setting_full_name(name)}" if plugin_cached_settings: plugin_settings = plugin_cached_settings else: @@ -265,8 +261,7 @@ class RhodeCodeAuthPluginBase(object): """ full_name = self._get_setting_full_name(name) type_ = self._get_setting_type(name) - db_setting = SettingsModel().create_or_update_setting( - full_name, value, type_) + db_setting = SettingsModel().create_or_update_setting(full_name, value, type_) return db_setting.app_settings_value def log_safe_settings(self, settings): @@ -311,8 +306,7 @@ class RhodeCodeAuthPluginBase(object): Deprecated method that indicates if this authentication plugin uses HTTP headers as authentication method. """ - warnings.warn( - 'Use is_headers_auth instead.', category=DeprecationWarning) + warnings.warn("Use is_headers_auth instead.", category=DeprecationWarning) return self.is_headers_auth @hybrid_property @@ -334,8 +328,8 @@ class RhodeCodeAuthPluginBase(object): self.acl_repo_name = acl_repo_name def allows_authentication_from( - self, user, allows_non_existing_user=True, - allowed_auth_plugins=None, allowed_auth_sources=None): + self, user, allows_non_existing_user=True, allowed_auth_plugins=None, allowed_auth_sources=None + ): """ Checks if this authentication module should accept a request for the current user. @@ -353,24 +347,24 @@ class RhodeCodeAuthPluginBase(object): :returns: boolean """ if not user and not allows_non_existing_user: - log.debug('User is empty but plugin does not allow empty users,' - 'not allowed to authenticate') + log.debug("User is empty but plugin does not allow empty users,not allowed to authenticate") return False expected_auth_plugins = allowed_auth_plugins or [self.name] - if user and (user.extern_type and - user.extern_type not in expected_auth_plugins): + if user and (user.extern_type and user.extern_type not in expected_auth_plugins): log.debug( - 'User `%s` is bound to `%s` auth type. Plugin allows only ' - '%s, skipping', user, user.extern_type, expected_auth_plugins) + "User `%s` is bound to `%s` auth type. Plugin allows only %s, skipping", + user, + user.extern_type, + expected_auth_plugins, + ) return False # by default accept both expected_auth_from = allowed_auth_sources or [HTTP_TYPE, VCS_TYPE] if self.auth_type not in expected_auth_from: - log.debug('Current auth source is %s but plugin only allows %s', - self.auth_type, expected_auth_from) + log.debug("Current auth source is %s but plugin only allows %s", self.auth_type, expected_auth_from) return False return True @@ -386,16 +380,15 @@ class RhodeCodeAuthPluginBase(object): """ user = None - log.debug( - 'Trying to fetch user `%s` from RhodeCode database', username) + log.debug("Trying to fetch user `%s` from RhodeCode database", username) if username: user = User.get_by_username_or_primary_email(username) else: - log.debug('provided username:`%s` is empty skipping...', username) + log.debug("provided username:`%s` is empty skipping...", username) if not user: - log.debug('User `%s` not found in database', username) + log.debug("User `%s` not found in database", username) else: - log.debug('Got DB user:%s', user) + log.debug("Got DB user:%s", user) return user def user_activation_state(self): @@ -430,15 +423,15 @@ class RhodeCodeAuthPluginBase(object): """ auth = self.auth(userobj, username, passwd, settings, **kwargs) if auth: - auth['_plugin'] = self.name - auth['_ttl_cache'] = self.get_ttl_cache(settings) + auth["_plugin"] = self.name + auth["_ttl_cache"] = self.get_ttl_cache(settings) # check if hash should be migrated ? - new_hash = auth.get('_hash_migrate') + new_hash = auth.get("_hash_migrate") if new_hash: # new_hash is a newly encrypted destination hash self._migrate_hash_to_bcrypt(username, passwd, new_hash) - if 'user_group_sync' not in auth: - auth['user_group_sync'] = False + if "user_group_sync" not in auth: + auth["user_group_sync"] = False return self._validate_auth_return(auth) return auth @@ -452,14 +445,14 @@ class RhodeCodeAuthPluginBase(object): cur_user.password = new_hash Session().add(cur_user) Session().flush() - log.info('Migrated user %s hash to bcrypt', cur_user) + log.info("Migrated user %s hash to bcrypt", cur_user) def _validate_auth_return(self, ret): if not isinstance(ret, dict): - raise Exception('returned value from auth must be a dict') + raise Exception("returned value from auth must be a dict") for k in self.auth_func_attrs: if k not in ret: - raise Exception('Missing %s attribute from returned data' % k) + raise Exception("Missing %s attribute from returned data" % k) return ret def get_ttl_cache(self, settings=None): @@ -468,20 +461,20 @@ class RhodeCodeAuthPluginBase(object): # performance > security, mostly due to LDAP/SVN, majority # of users pick cache_ttl to be enabled from rhodecode.authentication import plugin_default_auth_ttl + cache_ttl = plugin_default_auth_ttl if isinstance(self.AUTH_CACHE_TTL, int): # plugin cache set inside is more important than the settings value cache_ttl = self.AUTH_CACHE_TTL - elif 'cache_ttl' in plugin_settings: - cache_ttl = safe_int(plugin_settings.get('cache_ttl'), 0) + elif "cache_ttl" in plugin_settings: + cache_ttl = safe_int(plugin_settings.get("cache_ttl"), 0) plugin_cache_active = bool(cache_ttl and cache_ttl > 0) return plugin_cache_active, cache_ttl class RhodeCodeExternalAuthPlugin(RhodeCodeAuthPluginBase): - @hybrid_property def allows_creating_users(self): return True @@ -499,52 +492,45 @@ class RhodeCodeExternalAuthPlugin(RhodeCodeAuthPluginBase): def _authenticate(self, userobj, username, passwd, settings, **kwargs): # at this point _authenticate calls plugin's `auth()` function - auth = super()._authenticate( - userobj, username, passwd, settings, **kwargs) + auth = super()._authenticate(userobj, username, passwd, settings, **kwargs) if auth: # maybe plugin will clean the username ? # we should use the return value - username = auth['username'] + username = auth["username"] # if external source tells us that user is not active, we should # skip rest of the process. This can prevent from creating users in # RhodeCode when using external authentication, but if it's # inactive user we shouldn't create that user anyway - if auth['active_from_extern'] is False: - log.warning( - "User %s authenticated against %s, but is inactive", - username, self.__module__) + if auth["active_from_extern"] is False: + log.warning("User %s authenticated against %s, but is inactive", username, self.__module__) return None cur_user = User.get_by_username(username, case_insensitive=True) is_user_existing = cur_user is not None if is_user_existing: - log.debug('Syncing user `%s` from ' - '`%s` plugin', username, self.name) + log.debug("Syncing user `%s` from `%s` plugin", username, self.name) else: - log.debug('Creating non existing user `%s` from ' - '`%s` plugin', username, self.name) + log.debug("Creating non existing user `%s` from `%s` plugin", username, self.name) if self.allows_creating_users: - log.debug('Plugin `%s` allows to ' - 'create new users', self.name) + log.debug("Plugin `%s` allows to create new users", self.name) else: - log.debug('Plugin `%s` does not allow to ' - 'create new users', self.name) + log.debug("Plugin `%s` does not allow to create new users", self.name) user_parameters = { - 'username': username, - 'email': auth["email"], - 'firstname': auth["firstname"], - 'lastname': auth["lastname"], - 'active': auth["active"], - 'admin': auth["admin"], - 'extern_name': auth["extern_name"], - 'extern_type': self.name, - 'plugin': self, - 'allow_to_create_user': self.allows_creating_users, + "username": username, + "email": auth["email"], + "firstname": auth["firstname"], + "lastname": auth["lastname"], + "active": auth["active"], + "admin": auth["admin"], + "extern_name": auth["extern_name"], + "extern_type": self.name, + "plugin": self, + "allow_to_create_user": self.allows_creating_users, } if not is_user_existing: @@ -552,13 +538,13 @@ class RhodeCodeExternalAuthPlugin(RhodeCodeAuthPluginBase): # Randomize the PW because we don't need it, but don't want # them blank either passwd = PasswordGenerator().gen_password(length=16) - user_parameters['password'] = passwd + user_parameters["password"] = passwd else: # Since the password is required by create_or_update method of # UserModel, we need to set it explicitly. # The create_or_update method is smart and recognises the # password hashes as well. - user_parameters['password'] = cur_user.password + user_parameters["password"] = cur_user.password # we either create or update users, we also pass the flag # that controls if this method can actually do that. @@ -569,12 +555,10 @@ class RhodeCodeExternalAuthPlugin(RhodeCodeAuthPluginBase): # created from plugins. We store this info in _group_data JSON # field - if auth['user_group_sync']: + if auth["user_group_sync"]: try: - groups = auth['groups'] or [] - log.debug( - 'Performing user_group sync based on set `%s` ' - 'returned by `%s` plugin', groups, self.name) + groups = auth["groups"] or [] + log.debug("Performing user_group sync based on set `%s` returned by `%s` plugin", groups, self.name) UserGroupModel().enforce_groups(user, groups, self.name) except Exception: # for any reason group syncing fails, we should @@ -586,10 +570,8 @@ class RhodeCodeExternalAuthPlugin(RhodeCodeAuthPluginBase): class AuthLdapBase(object): - @classmethod def _build_servers(cls, ldap_server_type, ldap_server, port, use_resolver=True): - def host_resolver(host, port, full_resolve=True): """ Main work for this function is to prevent ldap connection issues, @@ -597,26 +579,25 @@ class AuthLdapBase(object): """ host = host.strip() if not full_resolve: - return f'{host}:{port}' + return f"{host}:{port}" - log.debug('LDAP: Resolving IP for LDAP host `%s`', host) + log.debug("LDAP: Resolving IP for LDAP host `%s`", host) try: ip = socket.gethostbyname(host) - log.debug('LDAP: Got LDAP host `%s` ip %s', host, ip) + log.debug("LDAP: Got LDAP host `%s` ip %s", host, ip) except Exception: - raise LdapConnectionError(f'Failed to resolve host: `{host}`') + raise LdapConnectionError(f"Failed to resolve host: `{host}`") - log.debug('LDAP: Checking if IP %s is accessible', ip) + log.debug("LDAP: Checking if IP %s is accessible", ip) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: s.connect((ip, int(port))) s.shutdown(socket.SHUT_RD) - log.debug('LDAP: connection to %s successful', ip) + log.debug("LDAP: connection to %s successful", ip) except Exception: - raise LdapConnectionError( - f'Failed to connect to host: `{host}:{port}`') + raise LdapConnectionError(f"Failed to connect to host: `{host}:{port}`") - return f'{host}:{port}' + return f"{host}:{port}" if len(ldap_server) == 1: # in case of single server use resolver to detect potential @@ -625,15 +606,18 @@ class AuthLdapBase(object): else: full_resolve = False - return ', '.join( - ["{}://{}".format( - ldap_server_type, - host_resolver(host, port, full_resolve=use_resolver and full_resolve)) - for host in ldap_server]) + return ", ".join( + [ + "{}://{}".format( + ldap_server_type, host_resolver(host, port, full_resolve=use_resolver and full_resolve) + ) + for host in ldap_server + ] + ) @classmethod def _get_server_list(cls, servers): - return [s.strip() for s in servers.split(',')] + return [s.strip() for s in servers.split(",")] @classmethod def get_uid(cls, username, server_addresses): @@ -645,8 +629,7 @@ class AuthLdapBase(object): @classmethod def validate_username(cls, username): if "," in username: - raise LdapUsernameError( - f"invalid character `,` in username: `{username}`") + raise LdapUsernameError(f"invalid character `,` in username: `{username}`") @classmethod def validate_password(cls, username, password): @@ -676,8 +659,9 @@ def get_authn_registry(registry=None) -> AuthenticationPluginRegistry: return authn_registry -def authenticate(username, password, environ=None, auth_type=None, - skip_missing=False, registry=None, acl_repo_name=None): +def authenticate( + username, password, environ=None, auth_type=None, skip_missing=False, registry=None, acl_repo_name=None +): """ Authentication function used for access control, It tries to authenticate based on enabled authentication modules. @@ -694,110 +678,105 @@ def authenticate(username, password, environ=None, auth_type=None, if not auth_type or auth_type not in [HTTP_TYPE, VCS_TYPE]: raise ValueError(f'auth type must be on of http, vcs got "{auth_type}" instead') - auth_credentials = (username and password) + auth_credentials = username and password headers_only = environ and not auth_credentials authn_registry = get_authn_registry(registry) plugins_to_check = authn_registry.get_plugins_for_authentication() - log.debug('authentication: headers=%s, username_and_passwd=%s', headers_only, bool(auth_credentials)) - log.debug('Starting ordered authentication chain using %s plugins', - [x.name for x in plugins_to_check]) + log.debug("authentication: headers=%s, username_and_passwd=%s", headers_only, bool(auth_credentials)) + log.debug("Starting ordered authentication chain using %s plugins", [x.name for x in plugins_to_check]) for plugin in plugins_to_check: plugin.set_auth_type(auth_type) plugin.set_calling_scope_repo(acl_repo_name) if headers_only and not plugin.is_headers_auth: - log.debug('Auth type is for headers only and plugin `%s` is not ' - 'headers plugin, skipping...', plugin.get_id()) + log.debug( + "Auth type is for headers only and plugin `%s` is not headers plugin, skipping...", plugin.get_id() + ) continue - log.debug('Trying authentication using ** %s **', plugin.get_id()) + log.debug("Trying authentication using ** %s **", plugin.get_id()) # load plugin settings from RhodeCode database plugin_settings = plugin.get_settings() plugin_sanitized_settings = plugin.log_safe_settings(plugin_settings) - log.debug('Plugin `%s` settings:%s', plugin.get_id(), plugin_sanitized_settings) + log.debug("Plugin `%s` settings:%s", plugin.get_id(), plugin_sanitized_settings) # use plugin's method of user extraction. - user = plugin.get_user(username, environ=environ, - settings=plugin_settings) + user = plugin.get_user(username, environ=environ, settings=plugin_settings) display_user = user.username if user else username - log.debug( - 'Plugin %s extracted user is `%s`', plugin.get_id(), display_user) + log.debug("Plugin %s extracted user is `%s`", plugin.get_id(), display_user) if not plugin.allows_authentication_from(user): - log.debug('Plugin %s does not accept user `%s` for authentication', - plugin.get_id(), display_user) + log.debug("Plugin %s does not accept user `%s` for authentication", plugin.get_id(), display_user) continue else: - log.debug('Plugin %s accepted user `%s` for authentication', - plugin.get_id(), display_user) + log.debug("Plugin %s accepted user `%s` for authentication", plugin.get_id(), display_user) - log.info('Authenticating user `%s` using %s plugin', - display_user, plugin.get_id()) + log.info("Authenticating user `%s` using %s plugin", display_user, plugin.get_id()) plugin_cache_active, cache_ttl = plugin.get_ttl_cache(plugin_settings) - log.debug('AUTH_CACHE_TTL for plugin `%s` active: %s (TTL: %s)', - plugin.get_id(), plugin_cache_active, cache_ttl) + log.debug( + "AUTH_CACHE_TTL for plugin `%s` active: %s (TTL: %s)", plugin.get_id(), plugin_cache_active, cache_ttl + ) - user_id = user.user_id if user else 'no-user' + user_id = user.user_id if user else "no-user" # don't cache for empty users plugin_cache_active = plugin_cache_active and user_id - cache_namespace_uid = f'cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{user_id}' - region = rc_cache.get_or_create_region('cache_perms', cache_namespace_uid) - - @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, - expiration_time=cache_ttl, - condition=plugin_cache_active) - def compute_auth( - cache_name, plugin_name, username, password): + cache_namespace_uid = f"cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{user_id}" + region = rc_cache.get_or_create_region("cache_perms", cache_namespace_uid) + @region.conditional_cache_on_arguments( + namespace=cache_namespace_uid, expiration_time=cache_ttl, condition=plugin_cache_active + ) + def compute_auth(cache_name, plugin_name, username, password): # _authenticate is a wrapper for .auth() method of plugin. # it checks if .auth() sends proper data. # For RhodeCodeExternalAuthPlugin it also maps users to # Database and maps the attributes returned from .auth() # to RhodeCode database. If this function returns data # then auth is correct. - log.debug('Running plugin `%s` _authenticate method ' - 'using username and password', plugin.get_id()) - return plugin._authenticate( - user, username, password, plugin_settings, - environ=environ or {}) + log.debug("Running plugin `%s` _authenticate method using username and password", plugin.get_id()) + return plugin._authenticate(user, username, password, plugin_settings, environ=environ or {}) start = time.time() # for environ based auth, password can be empty, but then the validation is # on the server that fills in the env data needed for authentication - plugin_user = compute_auth('auth', plugin.name, username, (password or '')) + plugin_user = compute_auth("auth", plugin.name, username, (password or "")) auth_time = time.time() - start - log.debug('Authentication for plugin `%s` completed in %.4fs, ' - 'expiration time of fetched cache %.1fs.', - plugin.get_id(), auth_time, cache_ttl, - extra={"plugin": plugin.get_id(), "time": auth_time}) + log.debug( + "Authentication for plugin `%s` completed in %.4fs, expiration time of fetched cache %.1fs.", + plugin.get_id(), + auth_time, + cache_ttl, + extra={"plugin": plugin.get_id(), "time": auth_time}, + ) - log.debug('PLUGIN USER DATA: %s', plugin_user) + log.debug("PLUGIN USER DATA: %s", plugin_user) statsd = StatsdClient.statsd if plugin_user: - log.debug('Plugin returned proper authentication data') + log.debug("Plugin returned proper authentication data") if statsd: elapsed_time_ms = round(1000.0 * auth_time) # use ms only - statsd.incr('rhodecode_login_success_total') - statsd.timing("rhodecode_login_timing.histogram", elapsed_time_ms, - tags=[f"plugin:{plugin.get_id()}"], - use_decimals=False + statsd.incr("rhodecode_login_success_total") + statsd.timing( + "rhodecode_login_timing.histogram", + elapsed_time_ms, + tags=[f"plugin:{plugin.get_id()}"], + use_decimals=False, ) return plugin_user # we failed to Auth because .auth() method didn't return proper user - log.debug("User `%s` failed to authenticate against %s", - display_user, plugin.get_id()) + log.debug("User `%s` failed to authenticate against %s", display_user, plugin.get_id()) if statsd: - statsd.incr('rhodecode_login_fail_total') + statsd.incr("rhodecode_login_fail_total") # case when we failed to authenticate against all defined plugins return None @@ -817,5 +796,5 @@ def chop_at(s, sub, inclusive=False): if pos == -1: return s if inclusive: - return s[:pos+len(sub)] + return s[: pos + len(sub)] return s[:pos] diff --git a/rhodecode/authentication/interface.py b/rhodecode/authentication/interface.py index b741971d..8fd115a5 100644 --- a/rhodecode/authentication/interface.py +++ b/rhodecode/authentication/interface.py @@ -24,4 +24,5 @@ class IAuthnPluginRegistry(Interface): Interface for the authentication plugin registry. Currently this is only used to register and retrieve it via pyramids registry. """ + pass diff --git a/rhodecode/authentication/plugins/auth_crowd.py b/rhodecode/authentication/plugins/auth_crowd.py index 62f3959d..64c0ccf2 100644 --- a/rhodecode/authentication/plugins/auth_crowd.py +++ b/rhodecode/authentication/plugins/auth_crowd.py @@ -20,7 +20,6 @@ RhodeCode authentication plugin for Atlassian CROWD """ - import colander import base64 import logging @@ -29,8 +28,7 @@ import urllib.error import urllib.parse from rhodecode.translation import _ -from rhodecode.authentication.base import ( - RhodeCodeExternalAuthPlugin, hybrid_property) +from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin, hybrid_property from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin from rhodecode.authentication.routes import AuthnPluginResourceBase from rhodecode.lib.colander_utils import strip_whitespace @@ -56,42 +54,46 @@ class CrowdAuthnResource(AuthnPluginResourceBase): class CrowdSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): host = colander.SchemaNode( colander.String(), - default='127.0.0.1', - description=_('The FQDN or IP of the Atlassian CROWD Server'), + default="127.0.0.1", + description=_("The FQDN or IP of the Atlassian CROWD Server"), preparer=strip_whitespace, - title=_('Host'), - widget='string') + title=_("Host"), + widget="string", + ) port = colander.SchemaNode( colander.Int(), default=8095, - description=_('The Port in use by the Atlassian CROWD Server'), + description=_("The Port in use by the Atlassian CROWD Server"), preparer=strip_whitespace, - title=_('Port'), + title=_("Port"), validator=colander.Range(min=0, max=65536), - widget='int') + widget="int", + ) app_name = colander.SchemaNode( colander.String(), - default='', - description=_('The Application Name to authenticate to CROWD'), + default="", + description=_("The Application Name to authenticate to CROWD"), preparer=strip_whitespace, - title=_('Application Name'), - widget='string') + title=_("Application Name"), + widget="string", + ) app_password = colander.SchemaNode( colander.String(), - default='', - description=_('The password to authenticate to CROWD'), + default="", + description=_("The password to authenticate to CROWD"), preparer=strip_whitespace, - title=_('Application Password'), - widget='password') + title=_("Application Password"), + widget="password", + ) admin_groups = colander.SchemaNode( colander.String(), - default='', - description=_('A comma separated list of group names that identify ' - 'users as RhodeCode Administrators'), - missing='', + default="", + description=_("A comma separated list of group names that identify users as RhodeCode Administrators"), + missing="", preparer=strip_whitespace, - title=_('Admin Groups'), - widget='string') + title=_("Admin Groups"), + widget="string", + ) class CrowdServer(object): @@ -110,14 +112,15 @@ class CrowdServer(object): passwd="some_passwd", version="1") """ - if 'port' not in kwargs: + if "port" not in kwargs: kwargs["port"] = "8095" self._logger = kwargs.get("logger", logging.getLogger(__name__)) - self._uri = "%s://%s:%s/crowd" % (kwargs.get("method", "http"), - kwargs.get("host", "127.0.0.1"), - kwargs.get("port", "8095")) - self.set_credentials(kwargs.get("user", ""), - kwargs.get("passwd", "")) + self._uri = "%s://%s:%s/crowd" % ( + kwargs.get("method", "http"), + kwargs.get("host", "127.0.0.1"), + kwargs.get("port", "8095"), + ) + self.set_credentials(kwargs.get("user", ""), kwargs.get("passwd", "")) self._version = kwargs.get("version", "latest") self._url_list = None self._appname = "crowd" @@ -133,19 +136,14 @@ class CrowdServer(object): handler = urllib.request.HTTPBasicAuthHandler(mgr) self.opener = urllib.request.build_opener(handler) - def _request(self, url, body=None, headers=None, - method=None, noformat=False, - empty_response_ok=False): - _headers = {"Content-type": "application/json", - "Accept": "application/json"} + def _request(self, url, body=None, headers=None, method=None, noformat=False, empty_response_ok=False): + _headers = {"Content-type": "application/json", "Accept": "application/json"} if self.user and self.passwd: authstring = base64.b64encode("{}:{}".format(self.user, self.passwd)) _headers["Authorization"] = "Basic %s" % authstring if headers: _headers.update(headers) - log.debug("Sent crowd: \n%s" - % (formatted_json({"url": url, "body": body, - "headers": _headers}))) + log.debug("Sent crowd: \n%s" % (formatted_json({"url": url, "body": body, "headers": _headers}))) request = urllib.request.Request(url, body, _headers) if method: request.get_method = lambda: method @@ -166,9 +164,7 @@ class CrowdServer(object): ret_val = msg except Exception as e: if not noformat: - ret_val = {"status": False, - "body": body, - "error": f"{e}\n{msg}"} + ret_val = {"status": False, "body": body, "error": f"{e}\n{msg}"} else: ret_val = None return ret_val @@ -176,45 +172,45 @@ class CrowdServer(object): def user_auth(self, username, password): """Authenticate a user against crowd. Returns brief information about the user.""" - url = ("%s/rest/usermanagement/%s/authentication?username=%s" - % (self._uri, self._version, username)) + url = "%s/rest/usermanagement/%s/authentication?username=%s" % (self._uri, self._version, username) body = json.dumps({"value": password}) return self._request(url, body) def user_groups(self, username): """Retrieve a list of groups to which this user belongs.""" - url = ("%s/rest/usermanagement/%s/user/group/nested?username=%s" - % (self._uri, self._version, username)) + url = "%s/rest/usermanagement/%s/user/group/nested?username=%s" % (self._uri, self._version, username) return self._request(url) class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): - uid = 'crowd' - _settings_unsafe_keys = ['app_password'] + uid = "crowd" + _settings_unsafe_keys = ["app_password"] def includeme(self, config): config.add_authn_plugin(self) config.add_authn_resource(self.get_id(), CrowdAuthnResource(self)) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_get', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='GET', - route_name='auth_home', - context=CrowdAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_get", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="GET", + route_name="auth_home", + context=CrowdAuthnResource, + ) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_post', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='POST', - route_name='auth_home', - context=CrowdAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_post", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="POST", + route_name="auth_home", + context=CrowdAuthnResource, + ) def get_settings_schema(self): return CrowdSettingsSchema() def get_display_name(self, load_from_settings=False): - return _('CROWD') + return _("CROWD") @classmethod def docs(cls): @@ -228,8 +224,8 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): return True def user_activation_state(self): - def_user_perms = User.get_default_user().AuthUser().permissions['global'] - return 'hg.extern_activate.auto' in def_user_perms + def_user_perms = User.get_default_user().AuthUser().permissions["global"] + return "hg.extern_activate.auto" in def_user_perms def auth(self, userobj, username, password, settings, **kwargs): """ @@ -243,7 +239,7 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): This is later validated for correctness """ if not username or not password: - log.debug('Empty username or password skipping...') + log.debug("Empty username or password skipping...") return None log.debug("Crowd settings: \n%s", formatted_json(settings)) @@ -259,26 +255,26 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): crowd_user["groups"] = [x["name"] for x in res["groups"]] # old attrs fetched from RhodeCode database - admin = getattr(userobj, 'admin', False) - active = getattr(userobj, 'active', True) - email = getattr(userobj, 'email', '') - username = getattr(userobj, 'username', username) - firstname = getattr(userobj, 'firstname', '') - lastname = getattr(userobj, 'lastname', '') - extern_type = getattr(userobj, 'extern_type', '') + admin = getattr(userobj, "admin", False) + active = getattr(userobj, "active", True) + email = getattr(userobj, "email", "") + username = getattr(userobj, "username", username) + firstname = getattr(userobj, "firstname", "") + lastname = getattr(userobj, "lastname", "") + extern_type = getattr(userobj, "extern_type", "") user_attrs = { - 'username': username, - 'firstname': crowd_user["first-name"] or firstname, - 'lastname': crowd_user["last-name"] or lastname, - 'groups': crowd_user["groups"], - 'user_group_sync': True, - 'email': crowd_user["email"] or email, - 'admin': admin, - 'active': active, - 'active_from_extern': crowd_user.get('active'), - 'extern_name': crowd_user["name"], - 'extern_type': extern_type, + "username": username, + "firstname": crowd_user["first-name"] or firstname, + "lastname": crowd_user["last-name"] or lastname, + "groups": crowd_user["groups"], + "user_group_sync": True, + "email": crowd_user["email"] or email, + "admin": admin, + "active": active, + "active_from_extern": crowd_user.get("active"), + "extern_name": crowd_user["name"], + "extern_type": extern_type, } # set an admin if we're in admin_groups of crowd @@ -286,10 +282,10 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): if group in user_attrs["groups"]: user_attrs["admin"] = True log.debug("Final crowd user object: \n%s", formatted_json(user_attrs)) - log.info('user `%s` authenticated correctly', user_attrs['username']) + log.info("user `%s` authenticated correctly", user_attrs["username"]) return user_attrs def includeme(config): - plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}' + plugin_id = f"egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}" plugin_factory(plugin_id).includeme(config) diff --git a/rhodecode/authentication/plugins/auth_headers.py b/rhodecode/authentication/plugins/auth_headers.py index 0b4c3900..2fd1bb39 100644 --- a/rhodecode/authentication/plugins/auth_headers.py +++ b/rhodecode/authentication/plugins/auth_headers.py @@ -20,8 +20,7 @@ import colander import logging from rhodecode.translation import _ -from rhodecode.authentication.base import ( - RhodeCodeExternalAuthPlugin, hybrid_property) +from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin, hybrid_property from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase from rhodecode.authentication.routes import AuthnPluginResourceBase from rhodecode.lib.colander_utils import strip_whitespace @@ -49,53 +48,60 @@ class HeadersAuthnResource(AuthnPluginResourceBase): class HeadersSettingsSchema(AuthnPluginSettingsSchemaBase): header = colander.SchemaNode( colander.String(), - default='REMOTE_USER', - description=_('Header to extract the user from'), + default="REMOTE_USER", + description=_("Header to extract the user from"), preparer=strip_whitespace, - title=_('Header'), - widget='string') + title=_("Header"), + widget="string", + ) fallback_header = colander.SchemaNode( colander.String(), - default='HTTP_X_FORWARDED_USER', - description=_('Header to extract the user from when main one fails'), + default="HTTP_X_FORWARDED_USER", + description=_("Header to extract the user from when main one fails"), preparer=strip_whitespace, - title=_('Fallback header'), - widget='string') + title=_("Fallback header"), + widget="string", + ) clean_username = colander.SchemaNode( colander.Boolean(), default=True, - description=_('Perform cleaning of user, if passed user has @ in ' - 'username then first part before @ is taken. ' - 'If there\'s \\ in the username only the part after ' - ' \\ is taken'), + description=_( + "Perform cleaning of user, if passed user has @ in " + "username then first part before @ is taken. " + "If there's \\ in the username only the part after " + " \\ is taken" + ), missing=False, - title=_('Clean username'), - widget='bool') + title=_("Clean username"), + widget="bool", + ) class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): - uid = 'headers' + uid = "headers" def includeme(self, config): config.add_authn_plugin(self) config.add_authn_resource(self.get_id(), HeadersAuthnResource(self)) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_get', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='GET', - route_name='auth_home', - context=HeadersAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_get", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="GET", + route_name="auth_home", + context=HeadersAuthnResource, + ) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_post', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='POST', - route_name='auth_home', - context=HeadersAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_post", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="POST", + route_name="auth_home", + context=HeadersAuthnResource, + ) def get_display_name(self, load_from_settings=False): - return _('Headers') + return _("Headers") def get_settings_schema(self): return HeadersSettingsSchema() @@ -112,37 +118,37 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): return True def user_activation_state(self): - def_user_perms = User.get_default_user().AuthUser().permissions['global'] - return 'hg.extern_activate.auto' in def_user_perms + def_user_perms = User.get_default_user().AuthUser().permissions["global"] + return "hg.extern_activate.auto" in def_user_perms def _clean_username(self, username): # Removing realm and domain from username - username = username.split('@')[0] - username = username.rsplit('\\')[-1] + username = username.split("@")[0] + username = username.rsplit("\\")[-1] return username def _get_username(self, environ, settings): username = None environ = environ or {} if not environ: - log.debug('got empty environ: %s', environ) + log.debug("got empty environ: %s", environ) settings = settings or {} - if settings.get('header'): - header = settings.get('header') + if settings.get("header"): + header = settings.get("header") username = environ.get(header) - log.debug('extracted %s:%s', header, username) + log.debug("extracted %s:%s", header, username) # fallback mode - if not username and settings.get('fallback_header'): - header = settings.get('fallback_header') + if not username and settings.get("fallback_header"): + header = settings.get("fallback_header") username = environ.get(header) - log.debug('extracted %s:%s', header, username) + log.debug("extracted %s:%s", header, username) - if username and str2bool(settings.get('clean_username')): - log.debug('Received username `%s` from headers', username) + if username and str2bool(settings.get("clean_username")): + log.debug("Received username `%s` from headers", username) username = self._clean_username(username) - log.debug('New cleanup user is:%s', username) + log.debug("New cleanup user is:%s", username) return username def get_user(self, username=None, **kwargs): @@ -153,8 +159,8 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): :param username: username if given to fetch :param kwargs: extra arguments needed for user fetching. """ - environ = kwargs.get('environ') or {} - settings = kwargs.get('settings') or {} + environ = kwargs.get("environ") or {} + settings = kwargs.get("settings") or {} username = self._get_username(environ, settings) # we got the username, so use default method now return super().get_user(username) @@ -176,19 +182,19 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): :param settings: :param kwargs: """ - environ = kwargs.get('environ') + environ = kwargs.get("environ") if not environ: - log.debug('Empty environ data skipping...') + log.debug("Empty environ data skipping...") return None if not userobj: - userobj = self.get_user('', environ=environ, settings=settings) + userobj = self.get_user("", environ=environ, settings=settings) # we don't care passed username/password for headers auth plugins. # only way to log in is using environ username = None if userobj: - username = getattr(userobj, 'username') + username = getattr(userobj, "username") if not username: # we don't have any objects in DB user doesn't exist extract @@ -200,32 +206,35 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): return None # old attrs fetched from RhodeCode database - admin = getattr(userobj, 'admin', False) - active = getattr(userobj, 'active', True) - email = getattr(userobj, 'email', '') - firstname = getattr(userobj, 'firstname', '') - lastname = getattr(userobj, 'lastname', '') - extern_type = getattr(userobj, 'extern_type', '') + admin = getattr(userobj, "admin", False) + active = getattr(userobj, "active", True) + email = getattr(userobj, "email", "") + firstname = getattr(userobj, "firstname", "") + lastname = getattr(userobj, "lastname", "") + extern_type = getattr(userobj, "extern_type", "") user_attrs = { - 'username': username, - 'firstname': safe_str(firstname or username), - 'lastname': safe_str(lastname or ''), - 'groups': [], - 'user_group_sync': False, - 'email': email or '', - 'admin': admin or False, - 'active': active, - 'active_from_extern': True, - 'extern_name': username, - 'extern_type': extern_type, + "username": username, + "firstname": safe_str(firstname or username), + "lastname": safe_str(lastname or ""), + "groups": [], + "user_group_sync": False, + "email": email or "", + "admin": admin or False, + "active": active, + "active_from_extern": True, + "extern_name": username, + "extern_type": extern_type, } - log.info('user `%s` authenticated correctly', user_attrs['username'], - extra={"action": "user_auth_ok", "auth_module": "auth_headers", "username": user_attrs["username"]}) + log.info( + "user `%s` authenticated correctly", + user_attrs["username"], + extra={"action": "user_auth_ok", "auth_module": "auth_headers", "username": user_attrs["username"]}, + ) return user_attrs def includeme(config): - plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}' + plugin_id = f"egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}" plugin_factory(plugin_id).includeme(config) diff --git a/rhodecode/authentication/plugins/auth_jasig_cas.py b/rhodecode/authentication/plugins/auth_jasig_cas.py index beb8deeb..c0fdc7ac 100644 --- a/rhodecode/authentication/plugins/auth_jasig_cas.py +++ b/rhodecode/authentication/plugins/auth_jasig_cas.py @@ -21,7 +21,6 @@ RhodeCode authentication plugin for Jasig CAS http://www.jasig.org/cas """ - import colander import logging import rhodecode @@ -31,8 +30,7 @@ import urllib.error from rhodecode.translation import _ -from rhodecode.authentication.base import ( - RhodeCodeExternalAuthPlugin, hybrid_property) +from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin, hybrid_property from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin from rhodecode.authentication.routes import AuthnPluginResourceBase from rhodecode.lib.colander_utils import strip_whitespace @@ -58,39 +56,42 @@ class JasigCasAuthnResource(AuthnPluginResourceBase): class JasigCasSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): service_url = colander.SchemaNode( colander.String(), - default='https://domain.com/cas/v1/tickets', - description=_('The url of the Jasig CAS REST service'), + default="https://domain.com/cas/v1/tickets", + description=_("The url of the Jasig CAS REST service"), preparer=strip_whitespace, - title=_('URL'), - widget='string') + title=_("URL"), + widget="string", + ) class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): - uid = 'jasig_cas' + uid = "jasig_cas" def includeme(self, config): config.add_authn_plugin(self) config.add_authn_resource(self.get_id(), JasigCasAuthnResource(self)) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_get', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='GET', - route_name='auth_home', - context=JasigCasAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_get", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="GET", + route_name="auth_home", + context=JasigCasAuthnResource, + ) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_post', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='POST', - route_name='auth_home', - context=JasigCasAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_post", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="POST", + route_name="auth_home", + context=JasigCasAuthnResource, + ) def get_settings_schema(self): return JasigCasSettingsSchema() def get_display_name(self, load_from_settings=False): - return _('Jasig-CAS') + return _("Jasig-CAS") @hybrid_property def name(self): @@ -104,8 +105,8 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): return True def user_activation_state(self): - def_user_perms = User.get_default_user().AuthUser().permissions['global'] - return 'hg.extern_activate.auto' in def_user_perms + def_user_perms = User.get_default_user().AuthUser().permissions["global"] + return "hg.extern_activate.auto" in def_user_perms def auth(self, userobj, username, password, settings, **kwargs): """ @@ -119,18 +120,19 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): This is later validated for correctness """ if not username or not password: - log.debug('Empty username or password skipping...') + log.debug("Empty username or password skipping...") return None log.debug("Jasig CAS settings: %s", settings) - params = urllib.parse.urlencode({'username': username, 'password': password}) - headers = {"Content-type": "application/x-www-form-urlencoded", - "Accept": "text/plain", - "User-Agent": "RhodeCode-auth-%s" % rhodecode.__version__} + params = urllib.parse.urlencode({"username": username, "password": password}) + headers = { + "Content-type": "application/x-www-form-urlencoded", + "Accept": "text/plain", + "User-Agent": "RhodeCode-auth-%s" % rhodecode.__version__, + } url = settings["service_url"] - log.debug("Sent Jasig CAS: \n%s", - {"url": url, "body": params, "headers": headers}) + log.debug("Sent Jasig CAS: \n%s", {"url": url, "body": params, "headers": headers}) request = urllib.request.Request(url, params, headers) try: urllib.request.urlopen(request) @@ -142,32 +144,32 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): return None # old attrs fetched from RhodeCode database - admin = getattr(userobj, 'admin', False) - active = getattr(userobj, 'active', True) - email = getattr(userobj, 'email', '') - username = getattr(userobj, 'username', username) - firstname = getattr(userobj, 'firstname', '') - lastname = getattr(userobj, 'lastname', '') - extern_type = getattr(userobj, 'extern_type', '') + admin = getattr(userobj, "admin", False) + active = getattr(userobj, "active", True) + email = getattr(userobj, "email", "") + username = getattr(userobj, "username", username) + firstname = getattr(userobj, "firstname", "") + lastname = getattr(userobj, "lastname", "") + extern_type = getattr(userobj, "extern_type", "") user_attrs = { - 'username': username, - 'firstname': safe_str(firstname or username), - 'lastname': safe_str(lastname or ''), - 'groups': [], - 'user_group_sync': False, - 'email': email or '', - 'admin': admin or False, - 'active': active, - 'active_from_extern': True, - 'extern_name': username, - 'extern_type': extern_type, + "username": username, + "firstname": safe_str(firstname or username), + "lastname": safe_str(lastname or ""), + "groups": [], + "user_group_sync": False, + "email": email or "", + "admin": admin or False, + "active": active, + "active_from_extern": True, + "extern_name": username, + "extern_type": extern_type, } - log.info('user `%s` authenticated correctly', user_attrs['username']) + log.info("user `%s` authenticated correctly", user_attrs["username"]) return user_attrs def includeme(config): - plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}' + plugin_id = f"egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}" plugin_factory(plugin_id).includeme(config) diff --git a/rhodecode/authentication/plugins/auth_ldap.py b/rhodecode/authentication/plugins/auth_ldap.py index 312c5ed4..5ba7866e 100644 --- a/rhodecode/authentication/plugins/auth_ldap.py +++ b/rhodecode/authentication/plugins/auth_ldap.py @@ -25,14 +25,11 @@ import traceback import colander from rhodecode.translation import _ -from rhodecode.authentication.base import ( - RhodeCodeExternalAuthPlugin, AuthLdapBase, hybrid_property) +from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin, AuthLdapBase, hybrid_property from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin from rhodecode.authentication.routes import AuthnPluginResourceBase from rhodecode.lib.colander_utils import strip_whitespace -from rhodecode.lib.exceptions import ( - LdapConnectionError, LdapUsernameError, LdapPasswordError, LdapImportError -) +from rhodecode.lib.exceptions import LdapConnectionError, LdapUsernameError, LdapPasswordError, LdapImportError from rhodecode.lib.str_utils import safe_str from rhodecode.model.db import User from rhodecode.model.validators import Missing @@ -65,36 +62,48 @@ class LdapAuthnResource(AuthnPluginResourceBase): class AuthLdap(AuthLdapBase): - default_tls_cert_dir = '/etc/openldap/cacerts' + default_tls_cert_dir = "/etc/openldap/cacerts" scope_labels = { - ldap.SCOPE_BASE: 'SCOPE_BASE', - ldap.SCOPE_ONELEVEL: 'SCOPE_ONELEVEL', - ldap.SCOPE_SUBTREE: 'SCOPE_SUBTREE', + ldap.SCOPE_BASE: "SCOPE_BASE", + ldap.SCOPE_ONELEVEL: "SCOPE_ONELEVEL", + ldap.SCOPE_SUBTREE: "SCOPE_SUBTREE", } - def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='', - tls_kind='PLAIN', tls_reqcert='DEMAND', tls_cert_file=None, - tls_cert_dir=None, ldap_version=3, - search_scope='SUBTREE', attr_login='uid', - ldap_filter='', timeout=None): + def __init__( + self, + server, + base_dn, + port=389, + bind_dn="", + bind_pass="", + tls_kind="PLAIN", + tls_reqcert="DEMAND", + tls_cert_file=None, + tls_cert_dir=None, + ldap_version=3, + search_scope="SUBTREE", + attr_login="uid", + ldap_filter="", + timeout=None, + ): if ldap == Missing: raise LdapImportError("Missing or incompatible ldap library") self.debug = False self.timeout = timeout or 60 * 5 self.ldap_version = ldap_version - self.ldap_server_type = 'ldap' + self.ldap_server_type = "ldap" self.TLS_KIND = tls_kind - if self.TLS_KIND == 'LDAPS': + if self.TLS_KIND == "LDAPS": port = port or 636 - self.ldap_server_type += 's' + self.ldap_server_type += "s" OPT_X_TLS_DEMAND = 2 - self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert, OPT_X_TLS_DEMAND) - self.TLS_CERT_FILE = tls_cert_file or '' + self.TLS_REQCERT = getattr(ldap, "OPT_X_TLS_%s" % tls_reqcert, OPT_X_TLS_DEMAND) + self.TLS_CERT_FILE = tls_cert_file or "" self.TLS_CERT_DIR = tls_cert_dir or self.default_tls_cert_dir # split server into list @@ -107,31 +116,29 @@ class AuthLdap(AuthLdapBase): self.LDAP_BIND_DN = safe_str(bind_dn) self.LDAP_BIND_PASS = safe_str(bind_pass) - self.SEARCH_SCOPE = getattr(ldap, 'SCOPE_%s' % search_scope) + self.SEARCH_SCOPE = getattr(ldap, "SCOPE_%s" % search_scope) self.BASE_DN = safe_str(base_dn) self.LDAP_FILTER = safe_str(ldap_filter) def _get_ldap_conn(self): - if self.debug: ldap.set_option(ldap.OPT_DEBUG_LEVEL, 255) - if self.TLS_CERT_FILE and hasattr(ldap, 'OPT_X_TLS_CACERTFILE'): + if self.TLS_CERT_FILE and hasattr(ldap, "OPT_X_TLS_CACERTFILE"): ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self.TLS_CERT_FILE) - elif hasattr(ldap, 'OPT_X_TLS_CACERTDIR'): + elif hasattr(ldap, "OPT_X_TLS_CACERTDIR"): ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, self.TLS_CERT_DIR) - if self.TLS_KIND != 'PLAIN': + if self.TLS_KIND != "PLAIN": ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, self.TLS_REQCERT) ldap.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF) ldap.set_option(ldap.OPT_RESTART, ldap.OPT_ON) # init connection now - ldap_servers = self._build_servers( - self.ldap_server_type, self.SERVER_ADDRESSES, self.LDAP_SERVER_PORT) - log.debug('initializing LDAP connection to:%s', ldap_servers) + ldap_servers = self._build_servers(self.ldap_server_type, self.SERVER_ADDRESSES, self.LDAP_SERVER_PORT) + log.debug("initializing LDAP connection to:%s", ldap_servers) ldap_conn = ldap.initialize(ldap_servers) ldap_conn.set_option(ldap.OPT_NETWORK_TIMEOUT, self.timeout) ldap_conn.set_option(ldap.OPT_TIMEOUT, self.timeout) @@ -142,37 +149,36 @@ class AuthLdap(AuthLdapBase): else: ldap_conn.protocol = ldap.VERSION3 - if self.TLS_KIND == 'START_TLS': + if self.TLS_KIND == "START_TLS": ldap_conn.start_tls_s() if self.LDAP_BIND_DN and self.LDAP_BIND_PASS: - log.debug('Trying simple_bind with password and given login DN: %r', - self.LDAP_BIND_DN) + log.debug("Trying simple_bind with password and given login DN: %r", self.LDAP_BIND_DN) ldap_conn.simple_bind_s(self.LDAP_BIND_DN, self.LDAP_BIND_PASS) - log.debug('simple_bind successful') + log.debug("simple_bind successful") return ldap_conn def fetch_attrs_from_simple_bind(self, ldap_conn, dn, username, password): scope = ldap.SCOPE_BASE scope_label = self.scope_labels.get(scope) - ldap_filter = '(objectClass=*)' + ldap_filter = "(objectClass=*)" try: - log.debug('Trying authenticated search bind with dn: %r SCOPE: %s (and filter: %s)', - dn, scope_label, ldap_filter) + log.debug( + "Trying authenticated search bind with dn: %r SCOPE: %s (and filter: %s)", dn, scope_label, ldap_filter + ) ldap_conn.simple_bind_s(dn, safe_str(password)) - response = ldap_conn.search_ext_s(dn, scope, ldap_filter, attrlist=['*', '+']) + response = ldap_conn.search_ext_s(dn, scope, ldap_filter, attrlist=["*", "+"]) if not response: - log.error('search bind returned empty results: %r', response) + log.error("search bind returned empty results: %r", response) return {} else: _dn, attrs = response[0] return attrs except ldap.INVALID_CREDENTIALS: - log.debug("LDAP rejected password for user '%s': %s, org_exc:", - username, dn, exc_info=True) + log.debug("LDAP rejected password for user '%s': %s, org_exc:", username, dn, exc_info=True) def authenticate_ldap(self, username, password): """ @@ -187,7 +193,7 @@ class AuthLdap(AuthLdapBase): uid = self.get_uid(username, self.SERVER_ADDRESSES) user_attrs = {} - dn = '' + dn = "" self.validate_password(username, password) self.validate_username(username) @@ -196,45 +202,37 @@ class AuthLdap(AuthLdapBase): ldap_conn = None try: ldap_conn = self._get_ldap_conn() - filter_ = '(&{}({}={}))'.format( - self.LDAP_FILTER, self.attr_login, username) - log.debug("Authenticating %r filter %s and scope: %s", - self.BASE_DN, filter_, scope_label) + filter_ = "(&{}({}={}))".format(self.LDAP_FILTER, self.attr_login, username) + log.debug("Authenticating %r filter %s and scope: %s", self.BASE_DN, filter_, scope_label) - ldap_objects = ldap_conn.search_ext_s( - self.BASE_DN, self.SEARCH_SCOPE, filter_, attrlist=['*', '+']) + ldap_objects = ldap_conn.search_ext_s(self.BASE_DN, self.SEARCH_SCOPE, filter_, attrlist=["*", "+"]) if not ldap_objects: - log.debug("No matching LDAP objects for authentication " - "of UID:'%s' username:(%s)", uid, username) + log.debug("No matching LDAP objects for authentication of UID:'%s' username:(%s)", uid, username) raise ldap.NO_SUCH_OBJECT() - log.debug('Found %s matching ldap object[s], trying to authenticate on each one now...', len(ldap_objects)) - for (dn, _attrs) in ldap_objects: + log.debug("Found %s matching ldap object[s], trying to authenticate on each one now...", len(ldap_objects)) + for dn, _attrs in ldap_objects: if dn is None: continue - user_attrs = self.fetch_attrs_from_simple_bind( - ldap_conn, dn, username, password) + user_attrs = self.fetch_attrs_from_simple_bind(ldap_conn, dn, username, password) if user_attrs: - log.debug('Got authenticated user attributes from DN:%s', dn) + log.debug("Got authenticated user attributes from DN:%s", dn) break else: - raise LdapPasswordError( - f'Failed to authenticate user `{username}` with given password') + raise LdapPasswordError(f"Failed to authenticate user `{username}` with given password") except ldap.NO_SUCH_OBJECT: - log.debug("LDAP says no such user '%s' (%s), org_exc:", - uid, username, exc_info=True) - raise LdapUsernameError('Unable to find user') + log.debug("LDAP says no such user '%s' (%s), org_exc:", uid, username, exc_info=True) + raise LdapUsernameError("Unable to find user") except ldap.SERVER_DOWN: org_exc = traceback.format_exc() - raise LdapConnectionError( - "LDAP can't access authentication server, org_exc:%s" % org_exc) + raise LdapConnectionError("LDAP can't access authentication server, org_exc:%s" % org_exc) finally: if ldap_conn: - log.debug('ldap: connection release') + log.debug("ldap: connection release") try: ldap_conn.unbind_s() except Exception: @@ -246,181 +244,215 @@ class AuthLdap(AuthLdapBase): class LdapSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): - tls_kind_choices = ['PLAIN', 'LDAPS', 'START_TLS'] - tls_reqcert_choices = ['NEVER', 'ALLOW', 'TRY', 'DEMAND', 'HARD'] - search_scope_choices = ['BASE', 'ONELEVEL', 'SUBTREE'] + tls_kind_choices = ["PLAIN", "LDAPS", "START_TLS"] + tls_reqcert_choices = ["NEVER", "ALLOW", "TRY", "DEMAND", "HARD"] + search_scope_choices = ["BASE", "ONELEVEL", "SUBTREE"] host = colander.SchemaNode( colander.String(), - default='', - description=_('Host[s] of the LDAP Server \n' - '(e.g., 192.168.2.154, or ldap-server.domain.com.\n ' - 'Multiple servers can be specified using commas'), + default="", + description=_( + "Host[s] of the LDAP Server \n" + "(e.g., 192.168.2.154, or ldap-server.domain.com.\n " + "Multiple servers can be specified using commas" + ), preparer=strip_whitespace, - title=_('LDAP Host'), - widget='string') + title=_("LDAP Host"), + widget="string", + ) port = colander.SchemaNode( colander.Int(), default=389, - description=_('Custom port that the LDAP server is listening on. ' - 'Default value is: 389, use 636 for LDAPS (SSL)'), + description=_( + "Custom port that the LDAP server is listening on. Default value is: 389, use 636 for LDAPS (SSL)" + ), preparer=strip_whitespace, - title=_('Port'), + title=_("Port"), validator=colander.Range(min=0, max=65536), - widget='int') + widget="int", + ) timeout = colander.SchemaNode( colander.Int(), default=60 * 5, - description=_('Timeout for LDAP connection'), + description=_("Timeout for LDAP connection"), preparer=strip_whitespace, - title=_('Connection timeout'), + title=_("Connection timeout"), validator=colander.Range(min=1), - widget='int') + widget="int", + ) dn_user = colander.SchemaNode( colander.String(), - default='', - description=_('Optional user DN/account to connect to LDAP if authentication is required. \n' - 'e.g., cn=admin,dc=mydomain,dc=com, or ' - 'uid=root,cn=users,dc=mydomain,dc=com, or admin@mydomain.com'), - missing='', + default="", + description=_( + "Optional user DN/account to connect to LDAP if authentication is required. \n" + "e.g., cn=admin,dc=mydomain,dc=com, or " + "uid=root,cn=users,dc=mydomain,dc=com, or admin@mydomain.com" + ), + missing="", preparer=strip_whitespace, - title=_('Bind account'), - widget='string') + title=_("Bind account"), + widget="string", + ) dn_pass = colander.SchemaNode( colander.String(), - default='', - description=_('Password to authenticate for given user DN.'), - missing='', + default="", + description=_("Password to authenticate for given user DN."), + missing="", preparer=strip_whitespace, - title=_('Bind account password'), - widget='password') + title=_("Bind account password"), + widget="password", + ) tls_kind = colander.SchemaNode( colander.String(), default=tls_kind_choices[0], - description=_('TLS Type'), - title=_('Connection Security'), + description=_("TLS Type"), + title=_("Connection Security"), validator=colander.OneOf(tls_kind_choices), - widget='select') + widget="select", + ) tls_reqcert = colander.SchemaNode( colander.String(), default=tls_reqcert_choices[0], - description=_('Require Cert over TLS?. Self-signed and custom ' - 'certificates can be used when\n `RhodeCode Certificate` ' - 'found in admin > settings > system info page is extended.'), - title=_('Certificate Checks'), + description=_( + "Require Cert over TLS?. Self-signed and custom " + "certificates can be used when\n `RhodeCode Certificate` " + "found in admin > settings > system info page is extended." + ), + title=_("Certificate Checks"), validator=colander.OneOf(tls_reqcert_choices), - widget='select') + widget="select", + ) tls_cert_file = colander.SchemaNode( colander.String(), - default='', - description=_('This specifies the PEM-format file path containing ' - 'certificates for use in TLS connection.\n' - 'If not specified `TLS Cert dir` will be used'), - title=_('TLS Cert file'), - missing='', - widget='string') + default="", + description=_( + "This specifies the PEM-format file path containing " + "certificates for use in TLS connection.\n" + "If not specified `TLS Cert dir` will be used" + ), + title=_("TLS Cert file"), + missing="", + widget="string", + ) tls_cert_dir = colander.SchemaNode( colander.String(), default=AuthLdap.default_tls_cert_dir, - description=_('This specifies the path of a directory that contains individual ' - 'CA certificates in separate files.'), - title=_('TLS Cert dir'), - widget='string') + description=_( + "This specifies the path of a directory that contains individual CA certificates in separate files." + ), + title=_("TLS Cert dir"), + widget="string", + ) base_dn = colander.SchemaNode( colander.String(), - default='', - description=_('Base DN to search. Dynamic bind is supported. Add `$login` marker ' - 'in it to be replaced with current user username \n' - '(e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com)'), - missing='', + default="", + description=_( + "Base DN to search. Dynamic bind is supported. Add `$login` marker " + "in it to be replaced with current user username \n" + "(e.g., dc=mydomain,dc=com, or ou=Users,dc=mydomain,dc=com)" + ), + missing="", preparer=strip_whitespace, - title=_('Base DN'), - widget='string') + title=_("Base DN"), + widget="string", + ) filter = colander.SchemaNode( colander.String(), - default='', - description=_('Filter to narrow results \n' - '(e.g., (&(objectCategory=Person)(objectClass=user)), or \n' - '(memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com)))'), - missing='', + default="", + description=_( + "Filter to narrow results \n" + "(e.g., (&(objectCategory=Person)(objectClass=user)), or \n" + "(memberof=cn=rc-login,ou=groups,ou=company,dc=mydomain,dc=com)))" + ), + missing="", preparer=strip_whitespace, - title=_('LDAP Search Filter'), - widget='string') + title=_("LDAP Search Filter"), + widget="string", + ) search_scope = colander.SchemaNode( colander.String(), default=search_scope_choices[2], - description=_('How deep to search LDAP. If unsure set to SUBTREE'), - title=_('LDAP Search Scope'), + description=_("How deep to search LDAP. If unsure set to SUBTREE"), + title=_("LDAP Search Scope"), validator=colander.OneOf(search_scope_choices), - widget='select') + widget="select", + ) attr_login = colander.SchemaNode( colander.String(), - default='uid', - description=_('LDAP Attribute to map to user name (e.g., uid, or sAMAccountName)'), + default="uid", + description=_("LDAP Attribute to map to user name (e.g., uid, or sAMAccountName)"), preparer=strip_whitespace, - title=_('Login Attribute'), - missing_msg=_('The LDAP Login attribute of the CN must be specified'), - widget='string') + title=_("Login Attribute"), + missing_msg=_("The LDAP Login attribute of the CN must be specified"), + widget="string", + ) attr_email = colander.SchemaNode( colander.String(), - default='', - description=_('LDAP Attribute to map to email address (e.g., mail).\n' - 'Emails are a crucial part of RhodeCode. \n' - 'If possible add a valid email attribute to ldap users.'), - missing='', + default="", + description=_( + "LDAP Attribute to map to email address (e.g., mail).\n" + "Emails are a crucial part of RhodeCode. \n" + "If possible add a valid email attribute to ldap users." + ), + missing="", preparer=strip_whitespace, - title=_('Email Attribute'), - widget='string') + title=_("Email Attribute"), + widget="string", + ) attr_firstname = colander.SchemaNode( colander.String(), - default='', - description=_('LDAP Attribute to map to first name (e.g., givenName)'), - missing='', + default="", + description=_("LDAP Attribute to map to first name (e.g., givenName)"), + missing="", preparer=strip_whitespace, - title=_('First Name Attribute'), - widget='string') + title=_("First Name Attribute"), + widget="string", + ) attr_lastname = colander.SchemaNode( colander.String(), - default='', - description=_('LDAP Attribute to map to last name (e.g., sn)'), - missing='', + default="", + description=_("LDAP Attribute to map to last name (e.g., sn)"), + missing="", preparer=strip_whitespace, - title=_('Last Name Attribute'), - widget='string') + title=_("Last Name Attribute"), + widget="string", + ) class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): - uid = 'ldap' + uid = "ldap" # used to define dynamic binding in the - DYNAMIC_BIND_VAR = '$login' - _settings_unsafe_keys = ['dn_pass'] + DYNAMIC_BIND_VAR = "$login" + _settings_unsafe_keys = ["dn_pass"] def includeme(self, config): config.add_authn_plugin(self) config.add_authn_resource(self.get_id(), LdapAuthnResource(self)) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_get', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='GET', - route_name='auth_home', - context=LdapAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_get", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="GET", + route_name="auth_home", + context=LdapAuthnResource, + ) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_post', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='POST', - route_name='auth_home', - context=LdapAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_post", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="POST", + route_name="auth_home", + context=LdapAuthnResource, + ) def get_settings_schema(self): return LdapSettingsSchema() def get_display_name(self, load_from_settings=False): - return _('LDAP') + return _("LDAP") @classmethod def docs(cls): @@ -434,8 +466,8 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): return True def user_activation_state(self): - def_user_perms = User.get_default_user().AuthUser().permissions['global'] - return 'hg.extern_activate.auto' in def_user_perms + def_user_perms = User.get_default_user().AuthUser().permissions["global"] + return "hg.extern_activate.auto" in def_user_perms def try_dynamic_binding(self, username, password, current_args): """ @@ -443,8 +475,8 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): present """ - org_bind = current_args['bind_dn'] - passwd = current_args['bind_pass'] + org_bind = current_args["bind_dn"] + passwd = current_args["bind_pass"] def has_bind_marker(_username): if self.DYNAMIC_BIND_VAR in _username: @@ -452,12 +484,12 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): # we only passed in user with "special" variable if org_bind and has_bind_marker(org_bind) and not passwd: - log.debug('Using dynamic user/password binding for ldap ' - 'authentication. Replacing `%s` with username', - self.DYNAMIC_BIND_VAR) - current_args['bind_dn'] = org_bind.replace( - self.DYNAMIC_BIND_VAR, username) - current_args['bind_pass'] = password + log.debug( + "Using dynamic user/password binding for ldap authentication. Replacing `%s` with username", + self.DYNAMIC_BIND_VAR, + ) + current_args["bind_dn"] = org_bind.replace(self.DYNAMIC_BIND_VAR, username) + current_args["bind_pass"] = password return current_args @@ -474,66 +506,69 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): """ if not username or not password: - log.debug('Empty username or password skipping...') + log.debug("Empty username or password skipping...") return None ldap_args = { - 'server': settings.get('host', ''), - 'base_dn': settings.get('base_dn', ''), - 'port': settings.get('port'), - 'bind_dn': settings.get('dn_user'), - 'bind_pass': settings.get('dn_pass'), - 'tls_kind': settings.get('tls_kind'), - 'tls_reqcert': settings.get('tls_reqcert'), - 'tls_cert_file': settings.get('tls_cert_file'), - 'tls_cert_dir': settings.get('tls_cert_dir'), - 'search_scope': settings.get('search_scope'), - 'attr_login': settings.get('attr_login'), - 'ldap_version': 3, - 'ldap_filter': settings.get('filter'), - 'timeout': settings.get('timeout') + "server": settings.get("host", ""), + "base_dn": settings.get("base_dn", ""), + "port": settings.get("port"), + "bind_dn": settings.get("dn_user"), + "bind_pass": settings.get("dn_pass"), + "tls_kind": settings.get("tls_kind"), + "tls_reqcert": settings.get("tls_reqcert"), + "tls_cert_file": settings.get("tls_cert_file"), + "tls_cert_dir": settings.get("tls_cert_dir"), + "search_scope": settings.get("search_scope"), + "attr_login": settings.get("attr_login"), + "ldap_version": 3, + "ldap_filter": settings.get("filter"), + "timeout": settings.get("timeout"), } ldap_attrs = self.try_dynamic_binding(username, password, ldap_args) - log.debug('Checking for ldap authentication.') + log.debug("Checking for ldap authentication.") try: auth_ldap = AuthLdap(**ldap_args) (user_dn, ldap_attrs) = auth_ldap.authenticate_ldap(username, password) - log.debug('Got ldap DN response %s', user_dn) + log.debug("Got ldap DN response %s", user_dn) def get_ldap_attr(k) -> str: - return safe_str(ldap_attrs.get(settings.get(k), [b''])[0]) + return safe_str(ldap_attrs.get(settings.get(k), [b""])[0]) # old attrs fetched from RhodeCode database - admin = getattr(userobj, 'admin', False) - active = getattr(userobj, 'active', True) - email = getattr(userobj, 'email', '') - username = getattr(userobj, 'username', username) - firstname = getattr(userobj, 'firstname', '') - lastname = getattr(userobj, 'lastname', '') - extern_type = getattr(userobj, 'extern_type', '') + admin = getattr(userobj, "admin", False) + active = getattr(userobj, "active", True) + email = getattr(userobj, "email", "") + username = getattr(userobj, "username", username) + firstname = getattr(userobj, "firstname", "") + lastname = getattr(userobj, "lastname", "") + extern_type = getattr(userobj, "extern_type", "") groups = [] user_attrs = { - 'username': username, - 'firstname': get_ldap_attr('attr_firstname') or firstname, - 'lastname': get_ldap_attr('attr_lastname') or lastname, - 'groups': groups, - 'user_group_sync': False, - 'email': get_ldap_attr('attr_email') or email, - 'admin': admin, - 'active': active, - 'active_from_extern': None, - 'extern_name': user_dn, - 'extern_type': extern_type, + "username": username, + "firstname": get_ldap_attr("attr_firstname") or firstname, + "lastname": get_ldap_attr("attr_lastname") or lastname, + "groups": groups, + "user_group_sync": False, + "email": get_ldap_attr("attr_email") or email, + "admin": admin, + "active": active, + "active_from_extern": None, + "extern_name": user_dn, + "extern_type": extern_type, } - log.debug('ldap user: %s', user_attrs) - log.info('user `%s` authenticated correctly', user_attrs['username'], - extra={"action": "user_auth_ok", "auth_module": "auth_ldap", "username": user_attrs["username"]}) + log.debug("ldap user: %s", user_attrs) + log.info( + "user `%s` authenticated correctly", + user_attrs["username"], + extra={"action": "user_auth_ok", "auth_module": "auth_ldap", "username": user_attrs["username"]}, + ) return user_attrs @@ -546,5 +581,5 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): def includeme(config): - plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}' + plugin_id = f"egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}" plugin_factory(plugin_id).includeme(config) diff --git a/rhodecode/authentication/plugins/auth_pam.py b/rhodecode/authentication/plugins/auth_pam.py index e440953a..3653adca 100644 --- a/rhodecode/authentication/plugins/auth_pam.py +++ b/rhodecode/authentication/plugins/auth_pam.py @@ -29,8 +29,7 @@ import re import socket from rhodecode.translation import _ -from rhodecode.authentication.base import ( - RhodeCodeExternalAuthPlugin, hybrid_property) +from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin, hybrid_property from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin from rhodecode.authentication.routes import AuthnPluginResourceBase from rhodecode.lib.colander_utils import strip_whitespace @@ -54,23 +53,24 @@ class PamAuthnResource(AuthnPluginResourceBase): class PamSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): service = colander.SchemaNode( colander.String(), - default='login', - description=_('PAM service name to use for authentication.'), + default="login", + description=_("PAM service name to use for authentication."), preparer=strip_whitespace, - title=_('PAM service name'), - widget='string') + title=_("PAM service name"), + widget="string", + ) gecos = colander.SchemaNode( colander.String(), - default=r'(?P.+),\s*(?P\w+)', - description=_('Regular expression for extracting user name/email etc. ' - 'from Unix userinfo.'), + default=r"(?P.+),\s*(?P\w+)", + description=_("Regular expression for extracting user name/email etc. from Unix userinfo."), preparer=strip_whitespace, - title=_('Gecos Regex'), - widget='string') + title=_("Gecos Regex"), + widget="string", + ) class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): - uid = 'pam' + uid = "pam" # PAM authentication can be slow. Repository operations involve a lot of # auth calls. Little caching helps speedup push/pull operations significantly AUTH_CACHE_TTL = 4 @@ -79,22 +79,24 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): config.add_authn_plugin(self) config.add_authn_resource(self.get_id(), PamAuthnResource(self)) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_get', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='GET', - route_name='auth_home', - context=PamAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_get", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="GET", + route_name="auth_home", + context=PamAuthnResource, + ) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_post', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='POST', - route_name='auth_home', - context=PamAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_post", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="POST", + route_name="auth_home", + context=PamAuthnResource, + ) def get_display_name(self, load_from_settings=False): - return _('PAM') + return _("PAM") @classmethod def docs(cls): @@ -112,7 +114,7 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): def auth(self, userobj, username, password, settings, **kwargs): if not username or not password: - log.debug('Empty username or password skipping...') + log.debug("Empty username or password skipping...") return None _pam = pam.pam() auth_result = _pam.authenticate(username, password, settings["service"]) @@ -121,31 +123,30 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): log.error("PAM was unable to authenticate user: %s", username) return None - log.debug('Got PAM response %s', auth_result) + log.debug("Got PAM response %s", auth_result) # old attrs fetched from RhodeCode database default_email = "{}@{}".format(username, socket.gethostname()) - admin = getattr(userobj, 'admin', False) - active = getattr(userobj, 'active', True) - email = getattr(userobj, 'email', '') or default_email - username = getattr(userobj, 'username', username) - firstname = getattr(userobj, 'firstname', '') - lastname = getattr(userobj, 'lastname', '') - extern_type = getattr(userobj, 'extern_type', '') + admin = getattr(userobj, "admin", False) + active = getattr(userobj, "active", True) + email = getattr(userobj, "email", "") or default_email + username = getattr(userobj, "username", username) + firstname = getattr(userobj, "firstname", "") + lastname = getattr(userobj, "lastname", "") + extern_type = getattr(userobj, "extern_type", "") user_attrs = { - 'username': username, - 'firstname': firstname, - 'lastname': lastname, - 'groups': [g.gr_name for g in grp.getgrall() - if username in g.gr_mem], - 'user_group_sync': True, - 'email': email, - 'admin': admin, - 'active': active, - 'active_from_extern': None, - 'extern_name': username, - 'extern_type': extern_type, + "username": username, + "firstname": firstname, + "lastname": lastname, + "groups": [g.gr_name for g in grp.getgrall() if username in g.gr_mem], + "user_group_sync": True, + "email": email, + "admin": admin, + "active": active, + "active_from_extern": None, + "extern_name": username, + "extern_type": extern_type, } try: @@ -153,18 +154,21 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): regex = settings["gecos"] match = re.search(regex, user_data.pw_gecos) if match: - user_attrs["firstname"] = match.group('first_name') - user_attrs["lastname"] = match.group('last_name') + user_attrs["firstname"] = match.group("first_name") + user_attrs["lastname"] = match.group("last_name") except Exception: log.warning("Cannot extract additional info for PAM user") pass log.debug("pamuser: %s", user_attrs) - log.info('user `%s` authenticated correctly', user_attrs['username'], - extra={"action": "user_auth_ok", "auth_module": "auth_pam", "username": user_attrs["username"]}) + log.info( + "user `%s` authenticated correctly", + user_attrs["username"], + extra={"action": "user_auth_ok", "auth_module": "auth_pam", "username": user_attrs["username"]}, + ) return user_attrs def includeme(config): - plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}' + plugin_id = f"egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}" plugin_factory(plugin_id).includeme(config) diff --git a/rhodecode/authentication/plugins/auth_rhodecode.py b/rhodecode/authentication/plugins/auth_rhodecode.py index 1529faee..c93ee142 100644 --- a/rhodecode/authentication/plugins/auth_rhodecode.py +++ b/rhodecode/authentication/plugins/auth_rhodecode.py @@ -28,8 +28,7 @@ from rhodecode.translation import _ from rhodecode.lib.utils2 import safe_bytes from rhodecode.model.db import User from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase, TwoFactorAuthnPluginSettingsSchemaMixin -from rhodecode.authentication.base import ( - RhodeCodeAuthPluginBase, hybrid_property, HTTP_TYPE, VCS_TYPE) +from rhodecode.authentication.base import RhodeCodeAuthPluginBase, hybrid_property, HTTP_TYPE, VCS_TYPE from rhodecode.authentication.routes import AuthnPluginResourceBase log = logging.getLogger(__name__) @@ -45,36 +44,38 @@ class RhodecodeAuthnResource(AuthnPluginResourceBase): class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): - uid = 'rhodecode' - AUTH_RESTRICTION_NONE = 'user_all' - AUTH_RESTRICTION_SUPER_ADMIN = 'user_super_admin' - AUTH_RESTRICTION_SCOPE_ALL = 'scope_all' - AUTH_RESTRICTION_SCOPE_HTTP = 'scope_http' - AUTH_RESTRICTION_SCOPE_VCS = 'scope_vcs' + uid = "rhodecode" + AUTH_RESTRICTION_NONE = "user_all" + AUTH_RESTRICTION_SUPER_ADMIN = "user_super_admin" + AUTH_RESTRICTION_SCOPE_ALL = "scope_all" + AUTH_RESTRICTION_SCOPE_HTTP = "scope_http" + AUTH_RESTRICTION_SCOPE_VCS = "scope_vcs" def includeme(self, config): config.add_authn_plugin(self) config.add_authn_resource(self.get_id(), RhodecodeAuthnResource(self)) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_get', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='GET', - route_name='auth_home', - context=RhodecodeAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_get", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="GET", + route_name="auth_home", + context=RhodecodeAuthnResource, + ) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_post', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='POST', - route_name='auth_home', - context=RhodecodeAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_post", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="POST", + route_name="auth_home", + context=RhodecodeAuthnResource, + ) def get_settings_schema(self): return RhodeCodeSettingsSchema() def get_display_name(self, load_from_settings=False): - return _('RhodeCode Internal') + return _("RhodeCode Internal") @classmethod def docs(cls): @@ -85,52 +86,56 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): return "rhodecode" def user_activation_state(self): - def_user_perms = User.get_default_user().AuthUser().permissions['global'] - return 'hg.register.auto_activate' in def_user_perms + def_user_perms = User.get_default_user().AuthUser().permissions["global"] + return "hg.register.auto_activate" in def_user_perms def allows_authentication_from( - self, user, allows_non_existing_user=True, - allowed_auth_plugins=None, allowed_auth_sources=None): + self, user, allows_non_existing_user=True, allowed_auth_plugins=None, allowed_auth_sources=None + ): """ Custom method for this auth that doesn't accept non existing users. We know that user exists in our database. """ allows_non_existing_user = False - return super().allows_authentication_from( - user, allows_non_existing_user=allows_non_existing_user) + return super().allows_authentication_from(user, allows_non_existing_user=allows_non_existing_user) def auth(self, userobj, username, password, settings, **kwargs): if not userobj: - log.debug('userobj was:%s skipping', userobj) + log.debug("userobj was:%s skipping", userobj) return None if userobj.extern_type != self.name: - log.warning("userobj:%s extern_type mismatch got:`%s` expected:`%s`", - userobj, userobj.extern_type, self.name) + log.warning( + "userobj:%s extern_type mismatch got:`%s` expected:`%s`", userobj, userobj.extern_type, self.name + ) return None # check scope of auth - scope_restriction = settings.get('scope_restriction', '') + scope_restriction = settings.get("scope_restriction", "") - if scope_restriction == self.AUTH_RESTRICTION_SCOPE_HTTP \ - and self.auth_type != HTTP_TYPE: - log.warning("userobj:%s tried scope type %s and scope restriction is set to %s", - userobj, self.auth_type, scope_restriction) + if scope_restriction == self.AUTH_RESTRICTION_SCOPE_HTTP and self.auth_type != HTTP_TYPE: + log.warning( + "userobj:%s tried scope type %s and scope restriction is set to %s", + userobj, + self.auth_type, + scope_restriction, + ) return None - if scope_restriction == self.AUTH_RESTRICTION_SCOPE_VCS \ - and self.auth_type != VCS_TYPE: - log.warning("userobj:%s tried scope type %s and scope restriction is set to %s", - userobj, self.auth_type, scope_restriction) + if scope_restriction == self.AUTH_RESTRICTION_SCOPE_VCS and self.auth_type != VCS_TYPE: + log.warning( + "userobj:%s tried scope type %s and scope restriction is set to %s", + userobj, + self.auth_type, + scope_restriction, + ) return None # check super-admin restriction - auth_restriction = settings.get('auth_restriction', '') + auth_restriction = settings.get("auth_restriction", "") - if auth_restriction == self.AUTH_RESTRICTION_SUPER_ADMIN \ - and userobj.admin is False: - log.warning("userobj:%s is not super-admin and auth restriction is set to %s", - userobj, auth_restriction) + if auth_restriction == self.AUTH_RESTRICTION_SUPER_ADMIN and userobj.admin is False: + log.warning("userobj:%s is not super-admin and auth restriction is set to %s", userobj, auth_restriction) return None user_attrs = { @@ -138,7 +143,7 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): "firstname": userobj.firstname, "lastname": userobj.lastname, "groups": [], - 'user_group_sync': False, + "user_group_sync": False, "email": userobj.email, "admin": userobj.admin, "active": userobj.active, @@ -150,70 +155,77 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): log.debug("User attributes:%s", user_attrs) if userobj.active: from rhodecode.lib import auth + crypto_backend = auth.crypto_backend() password_encoded = safe_bytes(password) - password_match, new_hash = crypto_backend.hash_check_with_upgrade( - password_encoded, userobj.password or '') + password_match, new_hash = crypto_backend.hash_check_with_upgrade(password_encoded, userobj.password or "") if password_match and new_hash: - log.debug('user %s properly authenticated, but ' - 'requires hash change to bcrypt', userobj) + log.debug("user %s properly authenticated, but requires hash change to bcrypt", userobj) # if password match, and we use OLD deprecated hash, # we should migrate this user hash password to the new hash # we store the new returned by hash_check_with_upgrade function - user_attrs['_hash_migrate'] = new_hash + user_attrs["_hash_migrate"] = new_hash if userobj.username == User.DEFAULT_USER and userobj.active: - log.info('user `%s` authenticated correctly as anonymous user', - userobj.username, - extra={"action": "user_auth_ok", "auth_module": "auth_rhodecode_anon", "username": userobj.username}) + log.info( + "user `%s` authenticated correctly as anonymous user", + userobj.username, + extra={ + "action": "user_auth_ok", + "auth_module": "auth_rhodecode_anon", + "username": userobj.username, + }, + ) return user_attrs elif (userobj.username == username or userobj.email == username) and password_match: - log.info('user `%s` authenticated correctly', userobj.username, - extra={"action": "user_auth_ok", "auth_module": "auth_rhodecode", "username": userobj.username}) + log.info( + "user `%s` authenticated correctly", + userobj.username, + extra={"action": "user_auth_ok", "auth_module": "auth_rhodecode", "username": userobj.username}, + ) return user_attrs - log.warning("user `%s` used a wrong password when " - "authenticating on this plugin", userobj.username) + log.warning("user `%s` used a wrong password when authenticating on this plugin", userobj.username) return None else: - log.warning('user `%s` failed to authenticate via %s, reason: account not ' - 'active.', username, self.name) + log.warning("user `%s` failed to authenticate via %s, reason: account not active.", username, self.name) return None class RhodeCodeSettingsSchema(TwoFactorAuthnPluginSettingsSchemaMixin, AuthnPluginSettingsSchemaBase): auth_restriction_choices = [ - (RhodeCodeAuthPlugin.AUTH_RESTRICTION_NONE, 'All users'), - (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN, 'Super admins only'), + (RhodeCodeAuthPlugin.AUTH_RESTRICTION_NONE, "All users"), + (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SUPER_ADMIN, "Super admins only"), ] auth_scope_choices = [ - (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_ALL, 'HTTP and VCS'), - (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_HTTP, 'HTTP only'), + (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_ALL, "HTTP and VCS"), + (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_HTTP, "HTTP only"), ] auth_restriction = colander.SchemaNode( colander.String(), default=auth_restriction_choices[0], - description=_('Allowed user types for authentication using this plugin.'), - title=_('User restriction'), + description=_("Allowed user types for authentication using this plugin."), + title=_("User restriction"), validator=colander.OneOf([x[0] for x in auth_restriction_choices]), - widget='select_with_labels', - choices=auth_restriction_choices + widget="select_with_labels", + choices=auth_restriction_choices, ) scope_restriction = colander.SchemaNode( colander.String(), default=auth_scope_choices[0], - description=_('Allowed protocols for authentication using this plugin. ' - 'VCS means GIT/HG/SVN. HTTP is web based login.'), - title=_('Scope restriction'), + description=_( + "Allowed protocols for authentication using this plugin. VCS means GIT/HG/SVN. HTTP is web based login." + ), + title=_("Scope restriction"), validator=colander.OneOf([x[0] for x in auth_scope_choices]), - widget='select_with_labels', - choices=auth_scope_choices + widget="select_with_labels", + choices=auth_scope_choices, ) def includeme(config): - plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}' + plugin_id = f"egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}" plugin_factory(plugin_id).includeme(config) diff --git a/rhodecode/authentication/plugins/auth_token.py b/rhodecode/authentication/plugins/auth_token.py index 03013373..b46e32df 100644 --- a/rhodecode/authentication/plugins/auth_token.py +++ b/rhodecode/authentication/plugins/auth_token.py @@ -25,8 +25,7 @@ import colander from rhodecode.authentication.schema import AuthnPluginSettingsSchemaBase from rhodecode.translation import _ -from rhodecode.authentication.base import ( - RhodeCodeAuthPluginBase, VCS_TYPE, hybrid_property) +from rhodecode.authentication.base import RhodeCodeAuthPluginBase, VCS_TYPE, hybrid_property from rhodecode.authentication.routes import AuthnPluginResourceBase from rhodecode.model.db import User, UserApiKeys, Repository @@ -47,32 +46,35 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): """ Enables usage of authentication tokens for vcs operations. """ - uid = 'token' - AUTH_RESTRICTION_SCOPE_VCS = 'scope_vcs' + + uid = "token" + AUTH_RESTRICTION_SCOPE_VCS = "scope_vcs" def includeme(self, config): config.add_authn_plugin(self) config.add_authn_resource(self.get_id(), RhodecodeAuthnResource(self)) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_get', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='GET', - route_name='auth_home', - context=RhodecodeAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_get", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="GET", + route_name="auth_home", + context=RhodecodeAuthnResource, + ) config.add_view( - 'rhodecode.authentication.views.AuthnPluginViewBase', - attr='settings_post', - renderer='rhodecode:templates/admin/auth/plugin_settings.mako', - request_method='POST', - route_name='auth_home', - context=RhodecodeAuthnResource) + "rhodecode.authentication.views.AuthnPluginViewBase", + attr="settings_post", + renderer="rhodecode:templates/admin/auth/plugin_settings.mako", + request_method="POST", + route_name="auth_home", + context=RhodecodeAuthnResource, + ) def get_settings_schema(self): return RhodeCodeSettingsSchema() def get_display_name(self, load_from_settings=False): - return _('Rhodecode Token') + return _("Rhodecode Token") @classmethod def docs(cls): @@ -83,22 +85,22 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): return "authtoken" def user_activation_state(self): - def_user_perms = User.get_default_user().AuthUser().permissions['global'] - return 'hg.register.auto_activate' in def_user_perms + def_user_perms = User.get_default_user().AuthUser().permissions["global"] + return "hg.register.auto_activate" in def_user_perms def allows_authentication_from( - self, user, allows_non_existing_user=True, - allowed_auth_plugins=None, allowed_auth_sources=None): + self, user, allows_non_existing_user=True, allowed_auth_plugins=None, allowed_auth_sources=None + ): """ Custom method for this auth that doesn't accept empty users. And also allows users from all other active plugins to use it and also authenticate against it. But only via vcs mode """ from rhodecode.authentication.base import get_authn_registry + authn_registry = get_authn_registry() - active_plugins = set( - [x.name for x in authn_registry.get_plugins_for_authentication()]) + active_plugins = set([x.name for x in authn_registry.get_plugins_for_authentication()]) active_plugins.discard(self.name) allowed_auth_plugins = [self.name] + list(active_plugins) @@ -106,13 +108,15 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): allowed_auth_sources = [VCS_TYPE] return super().allows_authentication_from( - user, allows_non_existing_user=False, + user, + allows_non_existing_user=False, allowed_auth_plugins=allowed_auth_plugins, - allowed_auth_sources=allowed_auth_sources) + allowed_auth_sources=allowed_auth_sources, + ) def auth(self, userobj, username, password, settings, **kwargs): if not userobj: - log.debug('userobj was:%s skipping', userobj) + log.debug("userobj was:%s skipping", userobj) return None user_attrs = { @@ -120,7 +124,7 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): "firstname": userobj.firstname, "lastname": userobj.lastname, "groups": [], - 'user_group_sync': False, + "user_group_sync": False, "email": userobj.email, "admin": userobj.admin, "active": userobj.active, @@ -129,7 +133,7 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): "extern_type": userobj.extern_type, } - log.debug('Authenticating user with args %s', user_attrs) + log.debug("Authenticating user with args %s", user_attrs) if userobj.active: # calling context repo for token scopes scope_repo_id = None @@ -138,38 +142,34 @@ class RhodeCodeAuthPlugin(RhodeCodeAuthPluginBase): scope_repo_id = repo.repo_id if repo else None token_match = userobj.authenticate_by_token( - password, roles=[UserApiKeys.ROLE_VCS], - scope_repo_id=scope_repo_id) + password, roles=[UserApiKeys.ROLE_VCS], scope_repo_id=scope_repo_id + ) if userobj.username == username and token_match: - log.info( - 'user `%s` successfully authenticated via %s', - user_attrs['username'], self.name) + log.info("user `%s` successfully authenticated via %s", user_attrs["username"], self.name) return user_attrs - log.warning('user `%s` failed to authenticate via %s, reason: bad or ' - 'inactive token.', username, self.name) + log.warning("user `%s` failed to authenticate via %s, reason: bad or inactive token.", username, self.name) else: - log.warning('user `%s` failed to authenticate via %s, reason: account not ' - 'active.', username, self.name) + log.warning("user `%s` failed to authenticate via %s, reason: account not active.", username, self.name) return None def includeme(config): - plugin_id = f'egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}' + plugin_id = f"egg:rhodecode-enterprise-ce#{RhodeCodeAuthPlugin.uid}" plugin_factory(plugin_id).includeme(config) class RhodeCodeSettingsSchema(AuthnPluginSettingsSchemaBase): auth_scope_choices = [ - (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS, 'VCS only'), + (RhodeCodeAuthPlugin.AUTH_RESTRICTION_SCOPE_VCS, "VCS only"), ] scope_restriction = colander.SchemaNode( colander.String(), default=auth_scope_choices[0], - description=_('Choose operation scope restriction when authenticating.'), - title=_('Scope restriction'), + description=_("Choose operation scope restriction when authenticating."), + title=_("Scope restriction"), validator=colander.OneOf([x[0] for x in auth_scope_choices]), - widget='select_with_labels', - choices=auth_scope_choices + widget="select_with_labels", + choices=auth_scope_choices, ) diff --git a/rhodecode/authentication/registry.py b/rhodecode/authentication/registry.py index 38cffa18..a6c520fb 100644 --- a/rhodecode/authentication/registry.py +++ b/rhodecode/authentication/registry.py @@ -33,9 +33,8 @@ log = logging.getLogger(__name__) @implementer(IAuthnPluginRegistry) class AuthenticationPluginRegistry(object): - # INI settings key to set a fallback authentication plugin. - fallback_plugin_key = 'rhodecode.auth_plugin_fallback' + fallback_plugin_key = "rhodecode.auth_plugin_fallback" def __init__(self, settings): self._plugins = {} @@ -44,8 +43,7 @@ class AuthenticationPluginRegistry(object): def add_authn_plugin(self, config, plugin): plugin_id = plugin.get_id() if plugin_id in self._plugins.keys(): - raise ConfigurationError( - 'Cannot register authentication plugin twice: "%s"', plugin_id) + raise ConfigurationError('Cannot register authentication plugin twice: "%s"', plugin_id) else: log.debug('Register authentication plugin: "%s"', plugin_id) self._plugins[plugin_id] = plugin @@ -69,7 +67,7 @@ class AuthenticationPluginRegistry(object): @region.conditional_cache_on_arguments(condition=cache) def _get_auth_plugins(name: str, key: str, fallback_plugin): - log.debug('auth-plugins: calculating plugins available for authentication') + log.debug("auth-plugins: calculating plugins available for authentication") _plugins = [] # Add all enabled and active plugins to the list. We iterate over the @@ -79,18 +77,14 @@ class AuthenticationPluginRegistry(object): for plugin_id in enabled_plugins: plugin = self.get_plugin(plugin_id) - if plugin is not None and plugin.is_active( - plugin_cached_settings=raw_settings): - + if plugin is not None and plugin.is_active(plugin_cached_settings=raw_settings): # inject settings into plugin, we can re-use the DB fetched settings here plugin._settings = plugin._propagate_settings(raw_settings) _plugins.append(plugin) # Add the fallback plugin from ini file. if fallback_plugin: - log.warning( - 'Using fallback authentication plugin from INI file: "%s"', - fallback_plugin) + log.warning('Using fallback authentication plugin from INI file: "%s"', fallback_plugin) plugin = self.get_plugin(fallback_plugin) if plugin is not None and plugin not in _plugins: plugin._settings = plugin._propagate_settings(raw_settings) @@ -110,30 +104,33 @@ class AuthenticationPluginRegistry(object): _get_auth_plugins = self.get_cache_call_method(cache=cache) start = time.time() - plugins = _get_auth_plugins('rhodecode_auth_plugins', 'v1', self._fallback_plugin) + plugins = _get_auth_plugins("rhodecode_auth_plugins", "v1", self._fallback_plugin) compute_time = time.time() - start - log.debug('cached method:%s took %.4fs', _get_auth_plugins.__name__, compute_time) + log.debug("cached method:%s took %.4fs", _get_auth_plugins.__name__, compute_time) statsd = StatsdClient.statsd if statsd: elapsed_time_ms = round(1000.0 * compute_time) # use ms only - statsd.timing("rhodecode_auth_plugins_timing.histogram", elapsed_time_ms, - use_decimals=False) + statsd.timing("rhodecode_auth_plugins_timing.histogram", elapsed_time_ms, use_decimals=False) return plugins @classmethod def get_cache_region(cls): - cache_namespace_uid = 'auth_plugins.v1' - region = rc_cache.get_or_create_region('cache_general', cache_namespace_uid) + cache_namespace_uid = "auth_plugins.v1" + region = rc_cache.get_or_create_region("cache_general", cache_namespace_uid) return region, cache_namespace_uid @classmethod def invalidate_auth_plugins_cache(cls, hard=True): region, namespace_key = cls.get_cache_region() - log.debug('Invalidation cache [%s] region %s for cache_key: %s', - 'invalidate_auth_plugins_cache', region, namespace_key) + log.debug( + "Invalidation cache [%s] region %s for cache_key: %s", + "invalidate_auth_plugins_cache", + region, + namespace_key, + ) # we use hard cleanup if invalidation is sent rc_cache.clear_cache_namespace(region, namespace_key, method=rc_cache.CLEAR_DELETE) diff --git a/rhodecode/authentication/routes.py b/rhodecode/authentication/routes.py index ddae5fe3..b3659f9e 100644 --- a/rhodecode/authentication/routes.py +++ b/rhodecode/authentication/routes.py @@ -41,7 +41,6 @@ class AuthnResourceBase(object): class AuthnPluginResourceBase(AuthnResourceBase): - def __init__(self, plugin): self.plugin = plugin self.__name__ = plugin.get_url_slug() @@ -52,12 +51,13 @@ class AuthnRootResource(AuthnResourceBase): """ This is the root traversal resource object for the authentication settings. """ + is_root = True def __init__(self): self._store = collections.OrderedDict() self._resource_name_map = {} - self.display_name = _('Authentication Plugins') + self.display_name = _("Authentication Plugins") def __getitem__(self, key): """ @@ -67,8 +67,7 @@ class AuthnRootResource(AuthnResourceBase): if self._is_item_active(key): return self._store[key] else: - raise KeyError('Authentication plugin "{}" is not active.'.format( - key)) + raise KeyError('Authentication plugin "{}" is not active.'.format(key)) def __iter__(self): for key in self._store.keys(): @@ -91,6 +90,7 @@ class AuthnRootResource(AuthnResourceBase): """ Returns a sorted list of sub resources for displaying purposes. """ + def default_sort_key(resource): return str.lower(safe_str(resource.display_name)) @@ -120,24 +120,27 @@ class AuthnRootResource(AuthnResourceBase): counter = 1 current = name while current in self._store.keys(): - current = f'{name}{counter}' + current = f"{name}{counter}" counter += 1 if counter > limit: raise ConfigurationError( - 'Cannot build unique name for traversal resource "%s" ' - 'registered by plugin "%s"', name, plugin_id) + 'Cannot build unique name for traversal resource "%s" registered by plugin "%s"', + name, + plugin_id, + ) return current # Allow plugin resources with identical names by rename duplicates. unique_name = _ensure_unique_name(resource.__name__) if unique_name != resource.__name__: - log.warning('Name collision for traversal resource "%s" registered ' - 'by authentication plugin "%s"', resource.__name__, - plugin_id) + log.warning( + 'Name collision for traversal resource "%s" registered by authentication plugin "%s"', + resource.__name__, + plugin_id, + ) resource.__name__ = unique_name - log.debug('Register traversal resource "%s" for plugin "%s"', - unique_name, plugin_id) + log.debug('Register traversal resource "%s" for plugin "%s"', unique_name, plugin_id) self._resource_name_map[unique_name] = plugin_id resource.__parent__ = self self._store[unique_name] = resource diff --git a/rhodecode/authentication/schema.py b/rhodecode/authentication/schema.py index 21176a99..dbd02e26 100644 --- a/rhodecode/authentication/schema.py +++ b/rhodecode/authentication/schema.py @@ -28,25 +28,28 @@ class AuthnPluginSettingsSchemaBase(colander.MappingSchema): It adds a few default settings (e.g., "enabled"), so that plugin authors don't have to maintain a bunch of boilerplate. """ + enabled = colander.SchemaNode( colander.Bool(), default=False, - description=_('Enable or disable this authentication plugin.'), + description=_("Enable or disable this authentication plugin."), missing=False, - title=_('Enabled'), - widget='bool', + title=_("Enabled"), + widget="bool", ) cache_ttl = colander.SchemaNode( colander.Int(), default=plugin_default_auth_ttl, - description=_('Amount of seconds to cache the authentication and ' - 'permissions check response call for this plugin. \n' - 'Useful for expensive calls like LDAP to improve the ' - 'performance of the system (0 means disabled).'), + description=_( + "Amount of seconds to cache the authentication and " + "permissions check response call for this plugin. \n" + "Useful for expensive calls like LDAP to improve the " + "performance of the system (0 means disabled)." + ), missing=0, - title=_('Auth Cache TTL'), + title=_("Auth Cache TTL"), validator=colander.Range(min=0, max=None), - widget='int', + widget="int", ) @@ -54,11 +57,12 @@ class TwoFactorAuthnPluginSettingsSchemaMixin(colander.MappingSchema): """ Mixin for extending plugins with two-factor authentication option. """ + global_2fa = colander.SchemaNode( colander.Bool(), default=False, - description=_('Force all users to use two factor authentication with this plugin.'), + description=_("Force all users to use two factor authentication with this plugin."), missing=False, - title=_('enforce 2FA for users'), - widget='bool', + title=_("enforce 2FA for users"), + widget="bool", ) diff --git a/rhodecode/authentication/tests/conftest.py b/rhodecode/authentication/tests/conftest.py index f04b28fc..c16f55eb 100644 --- a/rhodecode/authentication/tests/conftest.py +++ b/rhodecode/authentication/tests/conftest.py @@ -28,18 +28,18 @@ class EnabledAuthPlugin(object): """ def __init__(self, plugin): - self.new_value = {'egg:rhodecode-enterprise-ce#rhodecode', plugin.get_id()} + self.new_value = {"egg:rhodecode-enterprise-ce#rhodecode", plugin.get_id()} def __enter__(self): from rhodecode.model.settings import SettingsModel + self._old_value = SettingsModel().get_auth_plugins() - SettingsModel().create_or_update_setting( - 'auth_plugins', ','.join(self.new_value)) + SettingsModel().create_or_update_setting("auth_plugins", ",".join(self.new_value)) def __exit__(self, type, value, traceback): from rhodecode.model.settings import SettingsModel - SettingsModel().create_or_update_setting( - 'auth_plugins', ','.join(self._old_value)) + + SettingsModel().create_or_update_setting("auth_plugins", ",".join(self._old_value)) class DisabledAuthPlugin(object): @@ -53,26 +53,28 @@ class DisabledAuthPlugin(object): def __enter__(self): from rhodecode.model.settings import SettingsModel + self._old_value = SettingsModel().get_auth_plugins() new_value = [id_ for id_ in self._old_value if id_ != self.plugin_id] - SettingsModel().create_or_update_setting( - 'auth_plugins', ','.join(new_value)) + SettingsModel().create_or_update_setting("auth_plugins", ",".join(new_value)) def __exit__(self, type, value, traceback): from rhodecode.model.settings import SettingsModel - SettingsModel().create_or_update_setting( - 'auth_plugins', ','.join(self._old_value)) + + SettingsModel().create_or_update_setting("auth_plugins", ",".join(self._old_value)) -@pytest.fixture(params=[ - ('rhodecode.authentication.plugins.auth_crowd', 'egg:rhodecode-enterprise-ce#crowd'), - ('rhodecode.authentication.plugins.auth_headers', 'egg:rhodecode-enterprise-ce#headers'), - ('rhodecode.authentication.plugins.auth_jasig_cas', 'egg:rhodecode-enterprise-ce#jasig_cas'), - ('rhodecode.authentication.plugins.auth_ldap', 'egg:rhodecode-enterprise-ce#ldap'), - ('rhodecode.authentication.plugins.auth_pam', 'egg:rhodecode-enterprise-ce#pam'), - ('rhodecode.authentication.plugins.auth_rhodecode', 'egg:rhodecode-enterprise-ce#rhodecode'), - ('rhodecode.authentication.plugins.auth_token', 'egg:rhodecode-enterprise-ce#token'), -]) +@pytest.fixture( + params=[ + ("rhodecode.authentication.plugins.auth_crowd", "egg:rhodecode-enterprise-ce#crowd"), + ("rhodecode.authentication.plugins.auth_headers", "egg:rhodecode-enterprise-ce#headers"), + ("rhodecode.authentication.plugins.auth_jasig_cas", "egg:rhodecode-enterprise-ce#jasig_cas"), + ("rhodecode.authentication.plugins.auth_ldap", "egg:rhodecode-enterprise-ce#ldap"), + ("rhodecode.authentication.plugins.auth_pam", "egg:rhodecode-enterprise-ce#pam"), + ("rhodecode.authentication.plugins.auth_rhodecode", "egg:rhodecode-enterprise-ce#rhodecode"), + ("rhodecode.authentication.plugins.auth_token", "egg:rhodecode-enterprise-ce#token"), + ] +) def auth_plugin(request): """ Fixture that provides instance for each authentication plugin. These diff --git a/rhodecode/authentication/tests/functional/test_settings.py b/rhodecode/authentication/tests/functional/test_settings.py index 2bd67913..01517754 100644 --- a/rhodecode/authentication/tests/functional/test_settings.py +++ b/rhodecode/authentication/tests/functional/test_settings.py @@ -19,56 +19,46 @@ import pytest -from rhodecode.authentication.tests.conftest import ( - EnabledAuthPlugin, DisabledAuthPlugin) +from rhodecode.authentication.tests.conftest import EnabledAuthPlugin, DisabledAuthPlugin from rhodecode.apps._base import ADMIN_PREFIX -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") class TestAuthenticationSettings: - def test_auth_settings_global_view_get(self, app): - url = f'{ADMIN_PREFIX}/auth/' + url = f"{ADMIN_PREFIX}/auth/" response = app.get(url) assert response.status_code == 200 def test_plugin_settings_view_get(self, app, auth_plugin): - url = '{prefix}/auth/{name}'.format( - prefix=ADMIN_PREFIX, - name=auth_plugin.name) + url = "{prefix}/auth/{name}".format(prefix=ADMIN_PREFIX, name=auth_plugin.name) with EnabledAuthPlugin(auth_plugin): response = app.get(url) assert response.status_code == 200 def test_plugin_settings_view_post(self, app, auth_plugin, csrf_token): - url = '{prefix}/auth/{name}'.format( - prefix=ADMIN_PREFIX, - name=auth_plugin.name) + url = "{prefix}/auth/{name}".format(prefix=ADMIN_PREFIX, name=auth_plugin.name) params = { - 'enabled': True, - 'cache_ttl': 0, - 'csrf_token': csrf_token, + "enabled": True, + "cache_ttl": 0, + "csrf_token": csrf_token, } with EnabledAuthPlugin(auth_plugin): response = app.post(url, params=params) assert response.status_code in [200, 302] def test_plugin_settings_view_get_404(self, app, auth_plugin): - url = '{prefix}/auth/{name}'.format( - prefix=ADMIN_PREFIX, - name=auth_plugin.name) + url = "{prefix}/auth/{name}".format(prefix=ADMIN_PREFIX, name=auth_plugin.name) with DisabledAuthPlugin(auth_plugin): response = app.get(url, status=404) assert response.status_code == 404 def test_plugin_settings_view_post_404(self, app, auth_plugin, csrf_token): - url = '{prefix}/auth/{name}'.format( - prefix=ADMIN_PREFIX, - name=auth_plugin.name) + url = "{prefix}/auth/{name}".format(prefix=ADMIN_PREFIX, name=auth_plugin.name) params = { - 'enabled': True, - 'cache_ttl': 0, - 'csrf_token': csrf_token, + "enabled": True, + "cache_ttl": 0, + "csrf_token": csrf_token, } with DisabledAuthPlugin(auth_plugin): response = app.post(url, params=params, status=404) diff --git a/rhodecode/authentication/tests/test_auth_plugin_base.py b/rhodecode/authentication/tests/test_auth_plugin_base.py index 3ffb71b9..e7ed935c 100644 --- a/rhodecode/authentication/tests/test_auth_plugin_base.py +++ b/rhodecode/authentication/tests/test_auth_plugin_base.py @@ -24,5 +24,5 @@ from rhodecode.authentication.base import RhodeCodeAuthPluginBase def test_str_returns_plugin_id(): - plugin = RhodeCodeAuthPluginBase(plugin_id='stub_plugin_id') - assert str(plugin) == 'stub_plugin_id' + plugin = RhodeCodeAuthPluginBase(plugin_id="stub_plugin_id") + assert str(plugin) == "stub_plugin_id" diff --git a/rhodecode/authentication/views.py b/rhodecode/authentication/views.py index 4a26a04f..6b4bb01b 100644 --- a/rhodecode/authentication/views.py +++ b/rhodecode/authentication/views.py @@ -27,8 +27,7 @@ from pyramid.response import Response from rhodecode.apps._base import BaseAppView from rhodecode.authentication.base import get_authn_registry from rhodecode.lib import helpers as h -from rhodecode.lib.auth import ( - LoginRequired, HasPermissionAllDecorator, CSRFRequired) +from rhodecode.lib.auth import LoginRequired, HasPermissionAllDecorator, CSRFRequired from rhodecode.model.forms import AuthSettingsForm from rhodecode.model.meta import Session from rhodecode.model.settings import SettingsModel @@ -37,14 +36,13 @@ log = logging.getLogger(__name__) class AuthnPluginViewBase(BaseAppView): - def load_default_context(self): c = self._get_local_tmpl_context() self.plugin = self.context.plugin return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def settings_get(self, defaults=None, errors=None): """ View that displays the plugin settings as a form. @@ -58,20 +56,19 @@ class AuthnPluginViewBase(BaseAppView): # 1. Passed to this method 2. DB value 3. Schema default for node in schema: if node.name not in defaults: - defaults[node.name] = self.plugin.get_setting_by_name( - node.name, node.default) + defaults[node.name] = self.plugin.get_setting_by_name(node.name, node.default) template_context = { - 'defaults': defaults, - 'errors': errors, - 'plugin': self.context.plugin, - 'resource': self.context, + "defaults": defaults, + "errors": errors, + "plugin": self.context.plugin, + "resource": self.context, } return self._get_template_context(c, **template_context) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def settings_post(self): """ @@ -86,10 +83,7 @@ class AuthnPluginViewBase(BaseAppView): valid_data = schema.deserialize(data) except colander.Invalid as e: # Display error message and display form again. - h.flash( - _('Errors exist when saving plugin settings. ' - 'Please check the form inputs.'), - category='error') + h.flash(_("Errors exist when saving plugin settings. Please check the form inputs."), category="error") defaults = {key: data[key] for key in data if key in schema} return self.settings_get(errors=e.asdict(), defaults=defaults) @@ -103,8 +97,8 @@ class AuthnPluginViewBase(BaseAppView): authn_registry.invalidate_auth_plugins_cache() # Display success message and redirect. - h.flash(_('Auth settings updated successfully.'), category='success') - redirect_to = self.request.resource_path(self.context, route_name='auth_home') + h.flash(_("Auth settings updated successfully."), category="success") + redirect_to = self.request.resource_path(self.context, route_name="auth_home") return HTTPFound(redirect_to) @@ -115,7 +109,7 @@ class AuthSettingsView(BaseAppView): return c @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") def index(self, defaults=None, errors=None, prefix_error=False): c = self.load_default_context() @@ -125,18 +119,18 @@ class AuthSettingsView(BaseAppView): # Create template context and render it. template_context = { - 'resource': self.context, - 'available_plugins': authn_registry.get_plugins(), - 'enabled_plugins': enabled_plugins, + "resource": self.context, + "available_plugins": authn_registry.get_plugins(), + "enabled_plugins": enabled_plugins, } - html = render('rhodecode:templates/admin/auth/auth_settings.mako', - self._get_template_context(c, **template_context), - self.request) + html = render( + "rhodecode:templates/admin/auth/auth_settings.mako", + self._get_template_context(c, **template_context), + self.request, + ) # Create form default values and fill the form. - form_defaults = { - 'auth_plugins': ',\n'.join(enabled_plugins) - } + form_defaults = {"auth_plugins": ",\n".join(enabled_plugins)} form_defaults.update(defaults) html = formencode.htmlfill.render( html, @@ -144,40 +138,35 @@ class AuthSettingsView(BaseAppView): errors=errors, prefix_error=prefix_error, encoding="UTF-8", - force_defaults=False) + force_defaults=False, + ) return Response(html) @LoginRequired() - @HasPermissionAllDecorator('hg.admin') + @HasPermissionAllDecorator("hg.admin") @CSRFRequired() def auth_settings(self): _ = self.request.translate try: form = AuthSettingsForm(self.request.translate)() form_result = form.to_python(self.request.POST) - plugins = ','.join(form_result['auth_plugins']) - setting = SettingsModel().create_or_update_setting( - 'auth_plugins', plugins) + plugins = ",".join(form_result["auth_plugins"]) + setting = SettingsModel().create_or_update_setting("auth_plugins", plugins) Session().add(setting) Session().commit() SettingsModel().invalidate_settings_cache() - h.flash(_('Auth settings updated successfully.'), category='success') + h.flash(_("Auth settings updated successfully."), category="success") except formencode.Invalid as errors: e = errors.error_dict or {} - h.flash(_('Errors exist when saving plugin setting. ' - 'Please check the form inputs.'), category='error') - return self.index( - defaults=errors.value, - errors=e, - prefix_error=False) + h.flash(_("Errors exist when saving plugin setting. Please check the form inputs."), category="error") + return self.index(defaults=errors.value, errors=e, prefix_error=False) except Exception: - log.exception('Exception in auth_settings') - h.flash(_('Error occurred during update of auth settings.'), - category='error') + log.exception("Exception in auth_settings") + h.flash(_("Error occurred during update of auth settings."), category="error") authn_registry = get_authn_registry(self.request.registry) authn_registry.invalidate_auth_plugins_cache() - redirect_to = self.request.resource_path(self.context, route_name='auth_home') + redirect_to = self.request.resource_path(self.context, route_name="auth_home") return HTTPFound(redirect_to) diff --git a/rhodecode/bootstrap.py b/rhodecode/bootstrap.py index c93742d9..02d80e87 100644 --- a/rhodecode/bootstrap.py +++ b/rhodecode/bootstrap.py @@ -18,24 +18,24 @@ # bootstrap data available for tests and setup clean install -TEST_USER_ADMIN_LOGIN = 'test_admin' -TEST_USER_ADMIN_PASS = 'test12' -TEST_USER_ADMIN_EMAIL = 'test_admin@mail.com' +TEST_USER_ADMIN_LOGIN = "test_admin" +TEST_USER_ADMIN_PASS = "test12" +TEST_USER_ADMIN_EMAIL = "test_admin@mail.com" -TEST_USER_REGULAR_LOGIN = 'test_regular' -TEST_USER_REGULAR_PASS = 'test12' -TEST_USER_REGULAR_EMAIL = 'test_regular@mail.com' +TEST_USER_REGULAR_LOGIN = "test_regular" +TEST_USER_REGULAR_PASS = "test12" +TEST_USER_REGULAR_EMAIL = "test_regular@mail.com" -TEST_USER_REGULAR2_LOGIN = 'test_regular2' -TEST_USER_REGULAR2_PASS = 'test12' -TEST_USER_REGULAR2_EMAIL = 'test_regular2@mail.com' +TEST_USER_REGULAR2_LOGIN = "test_regular2" +TEST_USER_REGULAR2_PASS = "test12" +TEST_USER_REGULAR2_EMAIL = "test_regular2@mail.com" -HG_REPO = 'vcs_test_hg' -GIT_REPO = 'vcs_test_git' -SVN_REPO = 'vcs_test_svn' +HG_REPO = "vcs_test_hg" +GIT_REPO = "vcs_test_git" +SVN_REPO = "vcs_test_svn" -NEW_HG_REPO = 'vcs_test_hg_new' -NEW_GIT_REPO = 'vcs_test_git_new' +NEW_HG_REPO = "vcs_test_hg_new" +NEW_GIT_REPO = "vcs_test_git_new" -HG_FORK = 'vcs_test_hg_fork' -GIT_FORK = 'vcs_test_git_fork' +HG_FORK = "vcs_test_hg_fork" +GIT_FORK = "vcs_test_git_fork" diff --git a/rhodecode/config/conf.py b/rhodecode/config/conf.py index eef40820..93625b5a 100644 --- a/rhodecode/config/conf.py +++ b/rhodecode/config/conf.py @@ -19,6 +19,7 @@ """ Various config settings for RhodeCode """ + from rhodecode import EXTENSIONS from rhodecode.lib.utils2 import __get_lem @@ -27,9 +28,7 @@ from rhodecode.lib.utils2 import __get_lem # language map is also used by whoosh indexer, which for those specified # extensions will index it's content # custom extensions to lexers, format is 'ext': 'LexerClass' -extra = { - 'vbs': 'VbNet' -} +extra = {"vbs": "VbNet"} LANGUAGES_EXTENSIONS_MAP = __get_lem(extra) DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S" diff --git a/rhodecode/config/config_maker.py b/rhodecode/config/config_maker.py index 1b1b8bf4..2b355be1 100644 --- a/rhodecode/config/config_maker.py +++ b/rhodecode/config/config_maker.py @@ -42,195 +42,218 @@ def sanitize_settings_and_apply_defaults(global_config, settings): jn = os.path.join global_settings_maker = SettingsMaker(global_config) - global_settings_maker.make_setting('debug', default=False, parser='bool') - debug_enabled = asbool(global_config.get('debug')) + global_settings_maker.make_setting("debug", default=False, parser="bool") + debug_enabled = asbool(global_config.get("debug")) settings_maker = SettingsMaker(settings) - settings_maker.make_setting( - 'logging.autoconfigure', - default=False, - parser='bool') + settings_maker.make_setting("logging.autoconfigure", default=False, parser="bool") - ini_loc = os.path.dirname(global_config.get('__file__')) - logging_conf = jn(ini_loc, 'logging.ini') - settings_maker.enable_logging(logging_conf, level='INFO' if debug_enabled else 'DEBUG') + ini_loc = os.path.dirname(global_config.get("__file__")) + logging_conf = jn(ini_loc, "logging.ini") + settings_maker.enable_logging(logging_conf, level="INFO" if debug_enabled else "DEBUG") # Default includes, possible to change as a user - pyramid_includes = settings_maker.make_setting('pyramid.includes', [], parser='list:newline') - log.debug( - "Using the following pyramid.includes: %s", - pyramid_includes) + pyramid_includes = settings_maker.make_setting("pyramid.includes", [], parser="list:newline") + log.debug("Using the following pyramid.includes: %s", pyramid_includes) - settings_maker.make_setting('rhodecode.edition', 'Community Edition') - settings_maker.make_setting('rhodecode.edition_id', 'CE') + settings_maker.make_setting("rhodecode.edition", "Community Edition") + settings_maker.make_setting("rhodecode.edition_id", "CE") - if 'mako.default_filters' not in settings: + if "mako.default_filters" not in settings: # set custom default filters if we don't have it defined - settings['mako.imports'] = 'from rhodecode.lib.base import h_filter' - settings['mako.default_filters'] = 'h_filter' + settings["mako.imports"] = "from rhodecode.lib.base import h_filter" + settings["mako.default_filters"] = "h_filter" - if 'mako.directories' not in settings: - mako_directories = settings.setdefault('mako.directories', [ - # Base templates of the original application - 'rhodecode:templates', - ]) - log.debug( - "Using the following Mako template directories: %s", - mako_directories) + if "mako.directories" not in settings: + mako_directories = settings.setdefault( + "mako.directories", + [ + # Base templates of the original application + "rhodecode:templates", + ], + ) + log.debug("Using the following Mako template directories: %s", mako_directories) # NOTE(marcink): fix redis requirement for schema of connection since 3.X - if 'beaker.session.type' in settings and settings['beaker.session.type'] == 'ext:redis': - raw_url = settings['beaker.session.url'] - if not raw_url.startswith(('redis://', 'rediss://', 'unix://')): - settings['beaker.session.url'] = 'redis://' + raw_url + if "beaker.session.type" in settings and settings["beaker.session.type"] == "ext:redis": + raw_url = settings["beaker.session.url"] + if not raw_url.startswith(("redis://", "rediss://", "unix://")): + settings["beaker.session.url"] = "redis://" + raw_url - settings_maker.make_setting('__file__', global_config.get('__file__')) + settings_maker.make_setting("__file__", global_config.get("__file__")) # TODO: johbo: Re-think this, usually the call to config.include # should allow to pass in a prefix. - settings_maker.make_setting('rhodecode.api.url', '/_admin/api') + settings_maker.make_setting("rhodecode.api.url", "/_admin/api") # Sanitize generic settings. - settings_maker.make_setting('default_encoding', 'UTF-8', parser='list') - settings_maker.make_setting('gzip_responses', False, parser='bool') - settings_maker.make_setting('startup.import_repos', 'false', parser='bool') + settings_maker.make_setting("default_encoding", "UTF-8", parser="list") + settings_maker.make_setting("gzip_responses", False, parser="bool") + settings_maker.make_setting("startup.import_repos", "false", parser="bool") # License settings. - settings_maker.make_setting('license.hide_license_info', False, parser='bool') - settings_maker.make_setting('license.import_path', '') - settings_maker.make_setting('license.import_path_mode', 'if-missing') + settings_maker.make_setting("license.hide_license_info", False, parser="bool") + settings_maker.make_setting("license.import_path", "") + settings_maker.make_setting("license.import_path_mode", "if-missing") # statsd - settings_maker.make_setting('statsd.enabled', False, parser='bool') - settings_maker.make_setting('statsd.statsd_host', 'statsd-exporter', parser='string') - settings_maker.make_setting('statsd.statsd_port', 9125, parser='int') - settings_maker.make_setting('statsd.statsd_prefix', '') - settings_maker.make_setting('statsd.statsd_ipv6', False, parser='bool') + settings_maker.make_setting("statsd.enabled", False, parser="bool") + settings_maker.make_setting("statsd.statsd_host", "statsd-exporter", parser="string") + settings_maker.make_setting("statsd.statsd_port", 9125, parser="int") + settings_maker.make_setting("statsd.statsd_prefix", "") + settings_maker.make_setting("statsd.statsd_ipv6", False, parser="bool") - settings_maker.make_setting('vcs.svn.compatible_version', '') - settings_maker.make_setting('vcs.svn.redis_conn', 'redis://redis:6379/0') - settings_maker.make_setting('vcs.svn.proxy.enabled', True, parser='bool') - settings_maker.make_setting('vcs.svn.proxy.host', 'http://svn:8090', parser='string') - settings_maker.make_setting('vcs.hooks.protocol.v2', 'celery') - settings_maker.make_setting('vcs.hooks.host', '*') - settings_maker.make_setting('vcs.scm_app_implementation', 'http') - settings_maker.make_setting('vcs.server', '') - settings_maker.make_setting('vcs.server.protocol', 'http') - settings_maker.make_setting('vcs.server.enable', 'true', parser='bool') - settings_maker.make_setting('vcs.hooks.direct_calls', 'false', parser='bool') - settings_maker.make_setting('vcs.start_server', 'false', parser='bool') - settings_maker.make_setting('vcs.backends', 'hg, git, svn', parser='list') - settings_maker.make_setting('vcs.connection_timeout', 3600, parser='int') - settings_maker.make_setting('vcs.git.lfs.storage_location', - '/var/opt/rhodecode_repo_store/.cache/git_lfs_store', - parser='dir:ensured', default_when_empty=True) - settings_maker.make_setting('vcs.hg.largefiles.storage_location', - '/var/opt/rhodecode_repo_store/.cache/hg_largefiles_store', - parser='dir:ensured', default_when_empty=True) + settings_maker.make_setting("vcs.svn.compatible_version", "") + settings_maker.make_setting("vcs.svn.redis_conn", "redis://redis:6379/0") + settings_maker.make_setting("vcs.svn.proxy.enabled", True, parser="bool") + settings_maker.make_setting("vcs.svn.proxy.host", "http://svn:8090", parser="string") + settings_maker.make_setting("vcs.hooks.protocol.v2", "celery") + settings_maker.make_setting("vcs.hooks.host", "*") + settings_maker.make_setting("vcs.scm_app_implementation", "http") + settings_maker.make_setting("vcs.server", "") + settings_maker.make_setting("vcs.server.protocol", "http") + settings_maker.make_setting("vcs.server.enable", "true", parser="bool") + settings_maker.make_setting("vcs.hooks.direct_calls", "false", parser="bool") + settings_maker.make_setting("vcs.start_server", "false", parser="bool") + settings_maker.make_setting("vcs.backends", "hg, git, svn", parser="list") + settings_maker.make_setting("vcs.connection_timeout", 3600, parser="int") + settings_maker.make_setting( + "vcs.git.lfs.storage_location", + "/var/opt/rhodecode_repo_store/.cache/git_lfs_store", + parser="dir:ensured", + default_when_empty=True, + ) + settings_maker.make_setting( + "vcs.hg.largefiles.storage_location", + "/var/opt/rhodecode_repo_store/.cache/hg_largefiles_store", + parser="dir:ensured", + default_when_empty=True, + ) - settings_maker.make_setting('vcs.methods.cache', True, parser='bool') + settings_maker.make_setting("vcs.methods.cache", True, parser="bool") # repo_store path - settings_maker.make_setting('repo_store.path', '/var/opt/rhodecode_repo_store') + settings_maker.make_setting("repo_store.path", "/var/opt/rhodecode_repo_store") # Support legacy values of vcs.scm_app_implementation. Legacy # configurations may use 'rhodecode.lib.middleware.utils.scm_app_http', or # disabled since 4.13 'vcsserver.scm_app' which is now mapped to 'http'. - scm_app_impl = settings['vcs.scm_app_implementation'] - if scm_app_impl in ['rhodecode.lib.middleware.utils.scm_app_http', 'vcsserver.scm_app']: - settings['vcs.scm_app_implementation'] = 'http' + scm_app_impl = settings["vcs.scm_app_implementation"] + if scm_app_impl in ["rhodecode.lib.middleware.utils.scm_app_http", "vcsserver.scm_app"]: + settings["vcs.scm_app_implementation"] = "http" - settings_maker.make_setting('appenlight', False, parser='bool') + settings_maker.make_setting("appenlight", False, parser="bool") temp_store = tempfile.gettempdir() - tmp_cache_dir = jn(temp_store, 'rc_cache') + tmp_cache_dir = jn(temp_store, "rc_cache") # save default, cache dir, and use it for all backends later. default_cache_dir = settings_maker.make_setting( - 'cache_dir', - default=tmp_cache_dir, default_when_empty=True, - parser='dir:ensured') + "cache_dir", default=tmp_cache_dir, default_when_empty=True, parser="dir:ensured" + ) # exception store cache settings_maker.make_setting( - 'exception_tracker.store_path', - default=jn(default_cache_dir, 'exc_store'), default_when_empty=True, - parser='dir:ensured' + "exception_tracker.store_path", + default=jn(default_cache_dir, "exc_store"), + default_when_empty=True, + parser="dir:ensured", ) settings_maker.make_setting( - 'celerybeat-schedule.path', - default=jn(default_cache_dir, 'celerybeat_schedule', 'celerybeat-schedule.db'), default_when_empty=True, - parser='file:ensured' + "celerybeat-schedule.path", + default=jn(default_cache_dir, "celerybeat_schedule", "celerybeat-schedule.db"), + default_when_empty=True, + parser="file:ensured", ) # celery - broker_url = settings_maker.make_setting('celery.broker_url', 'redis://redis:6379/8', default_when_empty=True) - settings_maker.make_setting('celery.result_backend', broker_url) + broker_url = settings_maker.make_setting("celery.broker_url", "redis://redis:6379/8", default_when_empty=True) + settings_maker.make_setting("celery.result_backend", broker_url) - settings_maker.make_setting('exception_tracker.send_email', False, parser='bool') - settings_maker.make_setting('exception_tracker.email_prefix', '[RHODECODE ERROR]', default_when_empty=True) + settings_maker.make_setting("exception_tracker.send_email", False, parser="bool") + settings_maker.make_setting("exception_tracker.email_prefix", "[RHODECODE ERROR]", default_when_empty=True) # sessions, ensure file since no-value is memory - settings_maker.make_setting('beaker.session.type', 'file') - settings_maker.make_setting('beaker.session.data_dir', jn(default_cache_dir, 'session_data')) + settings_maker.make_setting("beaker.session.type", "file") + settings_maker.make_setting("beaker.session.data_dir", jn(default_cache_dir, "session_data")) # cache_general - settings_maker.make_setting('rc_cache.cache_general.backend', 'dogpile.cache.rc.file_namespace') - settings_maker.make_setting('rc_cache.cache_general.expiration_time', 60 * 60 * 12, parser='int') - settings_maker.make_setting('rc_cache.cache_general.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_general.db')) + settings_maker.make_setting("rc_cache.cache_general.backend", "dogpile.cache.rc.file_namespace") + settings_maker.make_setting("rc_cache.cache_general.expiration_time", 60 * 60 * 12, parser="int") + settings_maker.make_setting( + "rc_cache.cache_general.arguments.filename", jn(default_cache_dir, "rhodecode_cache_general.db") + ) # cache_perms - settings_maker.make_setting('rc_cache.cache_perms.backend', 'dogpile.cache.rc.file_namespace') - settings_maker.make_setting('rc_cache.cache_perms.expiration_time', 60 * 60, parser='int') - settings_maker.make_setting('rc_cache.cache_perms.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_perms_db')) + settings_maker.make_setting("rc_cache.cache_perms.backend", "dogpile.cache.rc.file_namespace") + settings_maker.make_setting("rc_cache.cache_perms.expiration_time", 60 * 60, parser="int") + settings_maker.make_setting( + "rc_cache.cache_perms.arguments.filename", jn(default_cache_dir, "rhodecode_cache_perms_db") + ) # cache_repo - settings_maker.make_setting('rc_cache.cache_repo.backend', 'dogpile.cache.rc.file_namespace') - settings_maker.make_setting('rc_cache.cache_repo.expiration_time', 60 * 60 * 24 * 30, parser='int') - settings_maker.make_setting('rc_cache.cache_repo.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_repo_db')) + settings_maker.make_setting("rc_cache.cache_repo.backend", "dogpile.cache.rc.file_namespace") + settings_maker.make_setting("rc_cache.cache_repo.expiration_time", 60 * 60 * 24 * 30, parser="int") + settings_maker.make_setting( + "rc_cache.cache_repo.arguments.filename", jn(default_cache_dir, "rhodecode_cache_repo_db") + ) # cache_license - settings_maker.make_setting('rc_cache.cache_license.backend', 'dogpile.cache.rc.file_namespace') - settings_maker.make_setting('rc_cache.cache_license.expiration_time', 60 * 5, parser='int') - settings_maker.make_setting('rc_cache.cache_license.arguments.filename', jn(default_cache_dir, 'rhodecode_cache_license_db')) + settings_maker.make_setting("rc_cache.cache_license.backend", "dogpile.cache.rc.file_namespace") + settings_maker.make_setting("rc_cache.cache_license.expiration_time", 60 * 5, parser="int") + settings_maker.make_setting( + "rc_cache.cache_license.arguments.filename", jn(default_cache_dir, "rhodecode_cache_license_db") + ) # cache_repo_longterm memory, 96H - settings_maker.make_setting('rc_cache.cache_repo_longterm.backend', 'dogpile.cache.rc.memory_lru') - settings_maker.make_setting('rc_cache.cache_repo_longterm.expiration_time', 345600, parser='int') - settings_maker.make_setting('rc_cache.cache_repo_longterm.max_size', 10000, parser='int') + settings_maker.make_setting("rc_cache.cache_repo_longterm.backend", "dogpile.cache.rc.memory_lru") + settings_maker.make_setting("rc_cache.cache_repo_longterm.expiration_time", 345600, parser="int") + settings_maker.make_setting("rc_cache.cache_repo_longterm.max_size", 10000, parser="int") # sql_cache_short - settings_maker.make_setting('rc_cache.sql_cache_short.backend', 'dogpile.cache.rc.memory_lru') - settings_maker.make_setting('rc_cache.sql_cache_short.expiration_time', 30, parser='int') - settings_maker.make_setting('rc_cache.sql_cache_short.max_size', 10000, parser='int') + settings_maker.make_setting("rc_cache.sql_cache_short.backend", "dogpile.cache.rc.memory_lru") + settings_maker.make_setting("rc_cache.sql_cache_short.expiration_time", 30, parser="int") + settings_maker.make_setting("rc_cache.sql_cache_short.max_size", 10000, parser="int") # archive_cache - settings_maker.make_setting('archive_cache.locking.url', 'redis://redis:6379/1') - settings_maker.make_setting('archive_cache.backend.type', 'filesystem') + settings_maker.make_setting("archive_cache.locking.url", "redis://redis:6379/1") + settings_maker.make_setting("archive_cache.backend.type", "filesystem") - settings_maker.make_setting('archive_cache.filesystem.store_dir', jn(default_cache_dir, 'archive_cache'), default_when_empty=True,) - settings_maker.make_setting('archive_cache.filesystem.cache_shards', 8, parser='int') - settings_maker.make_setting('archive_cache.filesystem.cache_size_gb', 10, parser='float') - settings_maker.make_setting('archive_cache.filesystem.eviction_policy', 'least-recently-stored') + settings_maker.make_setting( + "archive_cache.filesystem.store_dir", + jn(default_cache_dir, "archive_cache"), + default_when_empty=True, + ) + settings_maker.make_setting("archive_cache.filesystem.cache_shards", 8, parser="int") + settings_maker.make_setting("archive_cache.filesystem.cache_size_gb", 10, parser="float") + settings_maker.make_setting("archive_cache.filesystem.eviction_policy", "least-recently-stored") - settings_maker.make_setting('archive_cache.filesystem.retry', False, parser='bool') - settings_maker.make_setting('archive_cache.filesystem.retry_backoff', 1, parser='int') - settings_maker.make_setting('archive_cache.filesystem.retry_attempts', 10, parser='int') + settings_maker.make_setting("archive_cache.filesystem.retry", False, parser="bool") + settings_maker.make_setting("archive_cache.filesystem.retry_backoff", 1, parser="int") + settings_maker.make_setting("archive_cache.filesystem.retry_attempts", 10, parser="int") - settings_maker.make_setting('archive_cache.objectstore.url', 'http://s3-minio:9000', default_when_empty=True,) - settings_maker.make_setting('archive_cache.objectstore.key', '') - settings_maker.make_setting('archive_cache.objectstore.secret', '') - settings_maker.make_setting('archive_cache.objectstore.region', 'eu-central-1') - settings_maker.make_setting('archive_cache.objectstore.bucket', 'rhodecode-archive-cache', default_when_empty=True,) - settings_maker.make_setting('archive_cache.objectstore.bucket_shards', 8, parser='int') + settings_maker.make_setting( + "archive_cache.objectstore.url", + "http://s3-minio:9000", + default_when_empty=True, + ) + settings_maker.make_setting("archive_cache.objectstore.key", "") + settings_maker.make_setting("archive_cache.objectstore.secret", "") + settings_maker.make_setting("archive_cache.objectstore.region", "eu-central-1") + settings_maker.make_setting( + "archive_cache.objectstore.bucket", + "rhodecode-archive-cache", + default_when_empty=True, + ) + settings_maker.make_setting("archive_cache.objectstore.bucket_shards", 8, parser="int") - settings_maker.make_setting('archive_cache.objectstore.cache_size_gb', 10, parser='float') - settings_maker.make_setting('archive_cache.objectstore.eviction_policy', 'least-recently-stored') + settings_maker.make_setting("archive_cache.objectstore.cache_size_gb", 10, parser="float") + settings_maker.make_setting("archive_cache.objectstore.eviction_policy", "least-recently-stored") - settings_maker.make_setting('archive_cache.objectstore.retry', False, parser='bool') - settings_maker.make_setting('archive_cache.objectstore.retry_backoff', 1, parser='int') - settings_maker.make_setting('archive_cache.objectstore.retry_attempts', 10, parser='int') + settings_maker.make_setting("archive_cache.objectstore.retry", False, parser="bool") + settings_maker.make_setting("archive_cache.objectstore.retry_backoff", 1, parser="int") + settings_maker.make_setting("archive_cache.objectstore.retry_attempts", 10, parser="int") settings_maker.env_expand() diff --git a/rhodecode/config/environment.py b/rhodecode/config/environment.py index 9542db3c..935e55c7 100644 --- a/rhodecode/config/environment.py +++ b/rhodecode/config/environment.py @@ -40,9 +40,9 @@ def propagate_rhodecode_config(global_config, settings, config, full=True): rhodecode.PYRAMID_SETTINGS = settings_merged rhodecode.CONFIG = settings_merged - if full and 'default_user_id' not in rhodecode.CONFIG: - rhodecode.CONFIG['default_user_id'] = utils.get_default_user_id() - log.debug('set rhodecode.CONFIG data') + if full and "default_user_id" not in rhodecode.CONFIG: + rhodecode.CONFIG["default_user_id"] = utils.get_default_user_id() + log.debug("set rhodecode.CONFIG data") def load_pyramid_environment(global_config, settings): @@ -52,10 +52,10 @@ def load_pyramid_environment(global_config, settings): # TODO(marcink): probably not required anymore # configure channelstream, - settings_merged['channelstream_config'] = { - 'enabled': str2bool(settings_merged.get('channelstream.enabled', False)), - 'server': settings_merged.get('channelstream.server'), - 'secret': settings_merged.get('channelstream.secret') + settings_merged["channelstream_config"] = { + "enabled": str2bool(settings_merged.get("channelstream.enabled", False)), + "server": settings_merged.get("channelstream.server"), + "secret": settings_merged.get("channelstream.secret"), } # If this is a test run we prepare the test environment like @@ -64,6 +64,7 @@ def load_pyramid_environment(global_config, settings): if rhodecode.is_test: rhodecode.disable_error_handler = True from rhodecode import authentication + authentication.plugin_default_auth_ttl = 0 utils.initialize_test_environment(settings_merged) @@ -71,30 +72,28 @@ def load_pyramid_environment(global_config, settings): # Initialize the database connection. utils.initialize_database(settings_merged) - load_rcextensions(root_path=settings_merged['here']) + load_rcextensions(root_path=settings_merged["here"]) # Limit backends to `vcs.backends` from configuration, and preserve the order for alias in list(rhodecode.BACKENDS.keys()): - if alias not in settings['vcs.backends']: + if alias not in settings["vcs.backends"]: del rhodecode.BACKENDS[alias] - _sorted_backend = sorted(rhodecode.BACKENDS.items(), - key=lambda item: settings['vcs.backends'].index(item[0])) + _sorted_backend = sorted(rhodecode.BACKENDS.items(), key=lambda item: settings["vcs.backends"].index(item[0])) rhodecode.BACKENDS = collections.OrderedDict(_sorted_backend) - log.info('Enabled VCS backends: %s', list(rhodecode.BACKENDS.keys())) + log.info("Enabled VCS backends: %s", list(rhodecode.BACKENDS.keys())) # initialize vcs client and optionally run the server if enabled - vcs_server_uri = settings['vcs.server'] - vcs_server_enabled = settings['vcs.server.enable'] + vcs_server_uri = settings["vcs.server"] + vcs_server_enabled = settings["vcs.server.enable"] utils.configure_vcs(settings) # first run, to store data... propagate_rhodecode_config(global_config, settings, {}) - if vcs_server_enabled: connect_vcs(vcs_server_uri, utils.get_vcs_server_protocol(settings)) else: - log.warning('vcs-server not enabled, vcs connection unavailable') + log.warning("vcs-server not enabled, vcs connection unavailable") diff --git a/rhodecode/config/jsroutes.py b/rhodecode/config/jsroutes.py index b19bbaeb..4e10d8d0 100644 --- a/rhodecode/config/jsroutes.py +++ b/rhodecode/config/jsroutes.py @@ -16,12 +16,12 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ + def generate_jsroutes_content(jsroutes): statements = [] for url_name, url, fields in sorted(jsroutes): - statements.append( - "pyroutes.register('%s', '%s', %s);" % (url_name, url, fields)) - return u''' + statements.append("pyroutes.register('%s', '%s', %s);" % (url_name, url, fields)) + return """ /****************************************************************************** * * * DO NOT CHANGE THIS FILE MANUALLY * @@ -37,5 +37,4 @@ function registerRCRoutes() { // routes registration %s } -''' % '\n '.join(statements) - +""" % "\n ".join(statements) diff --git a/rhodecode/config/middleware.py b/rhodecode/config/middleware.py index f0b6eacc..40e77751 100644 --- a/rhodecode/config/middleware.py +++ b/rhodecode/config/middleware.py @@ -28,8 +28,7 @@ import pyramid.events from pyramid.wsgi import wsgiapp from pyramid.config import Configurator from pyramid.settings import asbool, aslist -from pyramid.httpexceptions import ( - HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound) +from pyramid.httpexceptions import HTTPException, HTTPError, HTTPInternalServerError, HTTPFound, HTTPNotFound from pyramid.renderers import render_to_response from rhodecode.model import meta @@ -49,8 +48,13 @@ from rhodecode.lib.plugins.utils import register_rhodecode_plugin from rhodecode.lib.utils2 import AttributeDict from rhodecode.lib.exc_tracking import store_exception, format_exc from rhodecode.subscribers import ( - auto_merge_pr_if_needed, scan_repositories_if_enabled, write_js_routes_if_enabled, - write_metadata_if_needed, write_usage_data, import_license_if_present) + auto_merge_pr_if_needed, + scan_repositories_if_enabled, + write_js_routes_if_enabled, + write_metadata_if_needed, + write_usage_data, + import_license_if_present, +) from rhodecode.lib.statsd_client import StatsdClient log = logging.getLogger(__name__) @@ -66,7 +70,7 @@ def should_load_all(): Returns if all application components should be loaded. In some cases it's desired to skip apps loading for faster shell script execution """ - ssh_cmd = os.environ.get('RC_CMD_SSH_WRAPPER') + ssh_cmd = os.environ.get("RC_CMD_SSH_WRAPPER") if ssh_cmd: return False @@ -86,7 +90,7 @@ def make_pyramid_app(global_config, **settings): """ start_time = time.time() - log.info('Pyramid app config starting') + log.info("Pyramid app config starting") sanitize_settings_and_apply_defaults(global_config, settings) @@ -125,7 +129,7 @@ def make_pyramid_app(global_config, **settings): meta.Session.remove() total_time = time.time() - start_time - log.info('Pyramid app created and configured in %.2fs', total_time) + log.info("Pyramid app created and configured in %.2fs", total_time) return pyramid_app @@ -135,9 +139,9 @@ def get_celery_config(settings): """ def key_converter(key_name): - pref = 'celery.' + pref = "celery." if key_name.startswith(pref): - return key_name[len(pref):].replace('.', '_').lower() + return key_name[len(pref) :].replace(".", "_").lower() def type_converter(parsed_key, value): # cast to int @@ -145,13 +149,13 @@ def get_celery_config(settings): return int(value) # cast to bool - if value.lower() in ['true', 'false', 'True', 'False']: - return value.lower() == 'true' + if value.lower() in ["true", "false", "True", "False"]: + return value.lower() == "true" return value celery_config = {} for k, v in settings.items(): - pref = 'celery.' + pref = "celery." if k.startswith(pref): celery_config[key_converter(k)] = type_converter(key_converter(k), v) @@ -179,16 +183,14 @@ def not_found_view(request): pyramid. """ - if not getattr(request, 'vcs_call', None): + if not getattr(request, "vcs_call", None): # handle like regular case with our error_handler return error_handler(HTTPNotFound(), request) # handle not found view as a vcs call settings = request.registry.settings - ae_client = getattr(request, 'ae_client', None) - vcs_app = VCSMiddleware( - HTTPNotFound(), request.registry, settings, - appenlight_client=ae_client) + ae_client = getattr(request, "ae_client", None) + vcs_app = VCSMiddleware(HTTPNotFound(), request.registry, settings, appenlight_client=ae_client) return wsgiapp(vcs_app)(None, request) @@ -197,7 +199,7 @@ def error_handler(exception, request): import rhodecode from rhodecode.lib import helpers - rhodecode_title = rhodecode.CONFIG.get('rhodecode_title') or 'RhodeCode' + rhodecode_title = rhodecode.CONFIG.get("rhodecode_title") or "RhodeCode" base_response = HTTPInternalServerError() # prefer original exception for the response since it may have headers set @@ -208,9 +210,7 @@ def error_handler(exception, request): if is_http_error(base_response): traceback_info = format_exc(request.exc_info) - log.error( - 'error occurred handling this request for path: %s, \n%s', - request.path, traceback_info) + log.error("error occurred handling this request for path: %s, \n%s", request.path, traceback_info) error_explanation = base_response.explanation or str(base_response) if base_response.status_code == 404: @@ -220,59 +220,57 @@ def error_handler(exception, request): c.error_explanation = error_explanation c.visual = AttributeDict() - c.visual.rhodecode_support_url = ( - request.registry.settings.get('rhodecode_support_url') or - request.route_url('rhodecode_support') + c.visual.rhodecode_support_url = request.registry.settings.get("rhodecode_support_url") or request.route_url( + "rhodecode_support" ) c.redirect_time = 0 c.rhodecode_name = rhodecode_title if not c.rhodecode_name: - c.rhodecode_name = 'Rhodecode' + c.rhodecode_name = "Rhodecode" c.causes = [] if is_http_error(base_response): - c.causes.append('Server is overloaded.') - c.causes.append('Server database connection is lost.') - c.causes.append('Server expected unhandled error.') + c.causes.append("Server is overloaded.") + c.causes.append("Server database connection is lost.") + c.causes.append("Server expected unhandled error.") - if hasattr(base_response, 'causes'): + if hasattr(base_response, "causes"): c.causes = base_response.causes c.messages = helpers.flash.pop_messages(request=request) exc_info = sys.exc_info() c.exception_id = id(exc_info) - c.show_exception_id = isinstance(base_response, VCSServerUnavailable) \ - or base_response.status_code > 499 - c.exception_id_url = request.route_url( - 'admin_settings_exception_tracker_show', exception_id=c.exception_id) + c.show_exception_id = isinstance(base_response, VCSServerUnavailable) or base_response.status_code > 499 + c.exception_id_url = request.route_url("admin_settings_exception_tracker_show", exception_id=c.exception_id) - debug_mode = rhodecode.ConfigGet().get_bool('debug') + debug_mode = rhodecode.ConfigGet().get_bool("debug") if c.show_exception_id: store_exception(c.exception_id, exc_info) c.exception_debug = debug_mode - c.exception_config_ini = rhodecode.CONFIG.get('__file__') + c.exception_config_ini = rhodecode.CONFIG.get("__file__") if debug_mode: try: from rich.traceback import install + install(show_locals=True) - log.debug('Installing rich tracebacks...') + log.debug("Installing rich tracebacks...") except ImportError: pass response = render_to_response( - '/errors/error_document.mako', {'c': c, 'h': helpers}, request=request, - response=base_response) + "/errors/error_document.mako", {"c": c, "h": helpers}, request=request, response=base_response + ) response.headers["X-RC-Exception-Id"] = str(c.exception_id) statsd = request.registry.statsd if statsd and base_response.status_code > 499: exc_type = f"{exception.__class__.__module__}.{exception.__class__.__name__}" - statsd.incr('rhodecode_exception_total', - tags=["exc_source:web", - f"http_code:{base_response.status_code}", - f"type:{exc_type}"]) + statsd.incr( + "rhodecode_exception_total", + tags=["exc_source:web", f"http_code:{base_response.status_code}", f"type:{exc_type}"], + ) return response @@ -280,68 +278,63 @@ def error_handler(exception, request): def includeme_first(config): # redirect automatic browser favicon.ico requests to correct place def favicon_redirect(context, request): - return HTTPFound( - request.static_path('rhodecode:public/images/favicon.ico')) + return HTTPFound(request.static_path("rhodecode:public/images/favicon.ico")) - config.add_view(favicon_redirect, route_name='favicon') - config.add_route('favicon', '/favicon.ico') + config.add_view(favicon_redirect, route_name="favicon") + config.add_route("favicon", "/favicon.ico") def robots_redirect(context, request): - return HTTPFound( - request.static_path('rhodecode:public/robots.txt')) + return HTTPFound(request.static_path("rhodecode:public/robots.txt")) - config.add_view(robots_redirect, route_name='robots') - config.add_route('robots', '/robots.txt') + config.add_view(robots_redirect, route_name="robots") + config.add_route("robots", "/robots.txt") - config.add_static_view( - '_static/deform', 'deform:static') - config.add_static_view( - '_static/rhodecode', path='rhodecode:public', cache_max_age=3600 * 24) + config.add_static_view("_static/deform", "deform:static") + config.add_static_view("_static/rhodecode", path="rhodecode:public", cache_max_age=3600 * 24) ce_auth_resources = [ - 'rhodecode.authentication.plugins.auth_crowd', - 'rhodecode.authentication.plugins.auth_headers', - 'rhodecode.authentication.plugins.auth_jasig_cas', - 'rhodecode.authentication.plugins.auth_ldap', - 'rhodecode.authentication.plugins.auth_pam', - 'rhodecode.authentication.plugins.auth_rhodecode', - 'rhodecode.authentication.plugins.auth_token', + "rhodecode.authentication.plugins.auth_crowd", + "rhodecode.authentication.plugins.auth_headers", + "rhodecode.authentication.plugins.auth_jasig_cas", + "rhodecode.authentication.plugins.auth_ldap", + "rhodecode.authentication.plugins.auth_pam", + "rhodecode.authentication.plugins.auth_rhodecode", + "rhodecode.authentication.plugins.auth_token", ] def includeme(config, auth_resources=None): from rhodecode.lib.celerylib.loader import configure_celery - log.debug('Initializing main includeme from %s', os.path.basename(__file__)) + + log.debug("Initializing main includeme from %s", os.path.basename(__file__)) settings = config.registry.settings config.set_request_factory(Request) # plugin information config.registry.rhodecode_plugins = collections.OrderedDict() - config.add_directive( - 'register_rhodecode_plugin', register_rhodecode_plugin) + config.add_directive("register_rhodecode_plugin", register_rhodecode_plugin) - config.add_directive('configure_celery', configure_celery) + config.add_directive("configure_celery", configure_celery) - if settings.get('appenlight', False): - config.include('appenlight_client.ext.pyramid_tween') + if settings.get("appenlight", False): + config.include("appenlight_client.ext.pyramid_tween") load_all = should_load_all() # Includes which are required. The application would fail without them. - config.include('pyramid_mako') - config.include('rhodecode.lib.rc_beaker') - config.include('rhodecode.lib.rc_cache') - config.include('rhodecode.lib.archive_cache') + config.include("pyramid_mako") + config.include("rhodecode.lib.rc_beaker") + config.include("rhodecode.lib.rc_cache") + config.include("rhodecode.lib.archive_cache") - config.include('rhodecode.apps._base.navigation') - config.include('rhodecode.apps._base.subscribers') - config.include('rhodecode.tweens') - config.include('rhodecode.authentication') + config.include("rhodecode.apps._base.navigation") + config.include("rhodecode.apps._base.subscribers") + config.include("rhodecode.tweens") + config.include("rhodecode.authentication") if load_all: - # load CE authentication plugins if auth_resources: @@ -351,83 +344,75 @@ def includeme(config, auth_resources=None): config.include(resource) # Auto discover authentication plugins and include their configuration. - if asbool(settings.get('auth_plugin.import_legacy_plugins', 'true')): + if asbool(settings.get("auth_plugin.import_legacy_plugins", "true")): from rhodecode.authentication import discover_legacy_plugins + discover_legacy_plugins(config) # apps if load_all: - log.debug('Starting config.include() calls') - config.include('rhodecode.api.includeme') - config.include('rhodecode.apps._base.includeme') - config.include('rhodecode.apps._base.navigation.includeme') - config.include('rhodecode.apps._base.subscribers.includeme') - config.include('rhodecode.apps.hovercards.includeme') - config.include('rhodecode.apps.ops.includeme') - config.include('rhodecode.apps.channelstream.includeme') - config.include('rhodecode.apps.file_store.includeme') - config.include('rhodecode.apps.admin.includeme') - config.include('rhodecode.apps.login.includeme') - config.include('rhodecode.apps.home.includeme') - config.include('rhodecode.apps.journal.includeme') + log.debug("Starting config.include() calls") + config.include("rhodecode.api.includeme") + config.include("rhodecode.apps._base.includeme") + config.include("rhodecode.apps._base.navigation.includeme") + config.include("rhodecode.apps._base.subscribers.includeme") + config.include("rhodecode.apps.hovercards.includeme") + config.include("rhodecode.apps.ops.includeme") + config.include("rhodecode.apps.channelstream.includeme") + config.include("rhodecode.apps.file_store.includeme") + config.include("rhodecode.apps.admin.includeme") + config.include("rhodecode.apps.login.includeme") + config.include("rhodecode.apps.home.includeme") + config.include("rhodecode.apps.journal.includeme") - config.include('rhodecode.apps.repository.includeme') - config.include('rhodecode.apps.repo_group.includeme') - config.include('rhodecode.apps.user_group.includeme') - config.include('rhodecode.apps.search.includeme') - config.include('rhodecode.apps.user_profile.includeme') - config.include('rhodecode.apps.user_group_profile.includeme') - config.include('rhodecode.apps.my_account.includeme') - config.include('rhodecode.apps.gist.includeme') + config.include("rhodecode.apps.repository.includeme") + config.include("rhodecode.apps.repo_group.includeme") + config.include("rhodecode.apps.user_group.includeme") + config.include("rhodecode.apps.search.includeme") + config.include("rhodecode.apps.user_profile.includeme") + config.include("rhodecode.apps.user_group_profile.includeme") + config.include("rhodecode.apps.my_account.includeme") + config.include("rhodecode.apps.gist.includeme") - config.include('rhodecode.apps.svn_support.includeme') - config.include('rhodecode.apps.ssh_support.includeme') - config.include('rhodecode.apps.debug_style') + config.include("rhodecode.apps.svn_support.includeme") + config.include("rhodecode.apps.ssh_support.includeme") + config.include("rhodecode.apps.debug_style") if load_all: - config.include('rhodecode.integrations.includeme') - config.include('rhodecode.integrations.routes.includeme') + config.include("rhodecode.integrations.includeme") + config.include("rhodecode.integrations.routes.includeme") - config.add_route('rhodecode_support', 'https://rhodecode.com/help/', static=True) - settings['default_locale_name'] = settings.get('lang', 'en') - config.add_translation_dirs('rhodecode:i18n/') + config.add_route("rhodecode_support", "https://rhodecode.com/help/", static=True) + settings["default_locale_name"] = settings.get("lang", "en") + config.add_translation_dirs("rhodecode:i18n/") # Add subscribers. if load_all: - log.debug('Adding subscribers...') + log.debug("Adding subscribers...") config.add_subscriber(auto_merge_pr_if_needed, rhodecode.events.PullRequestReviewEvent) - config.add_subscriber(scan_repositories_if_enabled, - pyramid.events.ApplicationCreated) - config.add_subscriber(write_metadata_if_needed, - pyramid.events.ApplicationCreated) - config.add_subscriber(write_usage_data, - pyramid.events.ApplicationCreated) - config.add_subscriber(write_js_routes_if_enabled, - pyramid.events.ApplicationCreated) - config.add_subscriber(import_license_if_present, - pyramid.events.ApplicationCreated) + config.add_subscriber(scan_repositories_if_enabled, pyramid.events.ApplicationCreated) + config.add_subscriber(write_metadata_if_needed, pyramid.events.ApplicationCreated) + config.add_subscriber(write_usage_data, pyramid.events.ApplicationCreated) + config.add_subscriber(write_js_routes_if_enabled, pyramid.events.ApplicationCreated) + config.add_subscriber(import_license_if_present, pyramid.events.ApplicationCreated) # Set the default renderer for HTML templates to mako. - config.add_mako_renderer('.html') + config.add_mako_renderer(".html") - config.add_renderer( - name='json_ext', - factory='rhodecode.lib.ext_json_renderer.pyramid_ext_json') + config.add_renderer(name="json_ext", factory="rhodecode.lib.ext_json_renderer.pyramid_ext_json") - config.add_renderer( - name='string_html', - factory='rhodecode.lib.string_renderer.html') + config.add_renderer(name="string_html", factory="rhodecode.lib.string_renderer.html") # include RhodeCode plugins - includes = aslist(settings.get('rhodecode.includes', [])) - log.debug('processing rhodecode.includes data...') + includes = aslist(settings.get("rhodecode.includes", [])) + log.debug("processing rhodecode.includes data...") for inc in includes: config.include(inc) # custom not found view, if our pyramid app doesn't know how to handle # the request pass it to potential VCS handling ap config.add_notfound_view(not_found_view) - if not settings.get('debugtoolbar.enabled', False): + if not settings.get("debugtoolbar.enabled", False): # disabled debugtoolbar handle all exceptions via the error_handlers config.add_view(error_handler, context=Exception) @@ -445,13 +430,11 @@ def wrap_app_in_wsgi_middlewares(pyramid_app, config): # enable https redirects based on HTTP_X_URL_SCHEME set by proxy pyramid_app = HttpsFixup(pyramid_app, settings) - pyramid_app, _ae_client = wrap_in_appenlight_if_enabled( - pyramid_app, settings) + pyramid_app, _ae_client = wrap_in_appenlight_if_enabled(pyramid_app, settings) registry.ae_client = _ae_client - if settings['gzip_responses']: - pyramid_app = make_gzip_middleware( - pyramid_app, settings, compress_level=1) + if settings["gzip_responses"]: + pyramid_app = make_gzip_middleware(pyramid_app, settings, compress_level=1) # this should be the outer most middleware in the wsgi stack since # middleware like Routes make database calls @@ -468,8 +451,8 @@ def wrap_app_in_wsgi_middlewares(pyramid_app, config): # '0 Current Checked out connections' at the end of a request, # if not, then something, somewhere is leaving a connection open pool = meta.get_engine().pool - log.debug('sa pool status: %s', pool.status()) + log.debug("sa pool status: %s", pool.status()) total = time.time() - start - log.debug('Request processing finalized: %.4fs', total) + log.debug("Request processing finalized: %.4fs", total) return pyramid_app_with_cleanup diff --git a/rhodecode/config/patches.py b/rhodecode/config/patches.py index b6505cd1..f5565327 100644 --- a/rhodecode/config/patches.py +++ b/rhodecode/config/patches.py @@ -31,19 +31,24 @@ Please keep the following principles in mind: def inspect_formatargspec(): - import inspect from inspect import formatannotation def backport_inspect_formatargspec( - args, varargs=None, varkw=None, defaults=None, - kwonlyargs=(), kwonlydefaults={}, annotations={}, - formatarg=str, - formatvarargs=lambda name: '*' + name, - formatvarkw=lambda name: '**' + name, - formatvalue=lambda value: '=' + repr(value), - formatreturns=lambda text: ' -> ' + text, - formatannotation=formatannotation): + args, + varargs=None, + varkw=None, + defaults=None, + kwonlyargs=(), + kwonlydefaults={}, + annotations={}, + formatarg=str, + formatvarargs=lambda name: "*" + name, + formatvarkw=lambda name: "**" + name, + formatvalue=lambda value: "=" + repr(value), + formatreturns=lambda text: " -> " + text, + formatannotation=formatannotation, + ): """Copy formatargspec from python 3.7 standard library. Python 3 has deprecated formatargspec and requested that Signature be used instead, however this requires a full reimplementation @@ -58,7 +63,7 @@ def inspect_formatargspec(): def formatargandannotation(arg): result = formatarg(arg) if arg in annotations: - result += ': ' + formatannotation(annotations[arg]) + result += ": " + formatannotation(annotations[arg]) return result specs = [] @@ -73,7 +78,7 @@ def inspect_formatargspec(): specs.append(formatvarargs(formatargandannotation(varargs))) else: if kwonlyargs: - specs.append('*') + specs.append("*") if kwonlyargs: for kwonlyarg in kwonlyargs: spec = formatargandannotation(kwonlyarg) @@ -82,9 +87,9 @@ def inspect_formatargspec(): specs.append(spec) if varkw is not None: specs.append(formatvarkw(formatargandannotation(varkw))) - result = '(' + ', '.join(specs) + ')' - if 'return' in annotations: - result += formatreturns(formatannotation(annotations['return'])) + result = "(" + ", ".join(specs) + ")" + if "return" in annotations: + result += formatreturns(formatannotation(annotations["return"])) return result # NOTE: inject for python3.11 @@ -105,7 +110,7 @@ def inspect_getargspec(): """ Private helper that checks if a function is a cython function. """ - return func.__class__.__name__ == 'cython_function_or_method' + return func.__class__.__name__ == "cython_function_or_method" def unwrap(func): """ @@ -125,11 +130,11 @@ def inspect_getargspec(): """ f = func # remember the original func for error reporting memo = {id(f)} # Memoise by id to tolerate non-hashable objects - while hasattr(func, '__wrapped__'): + while hasattr(func, "__wrapped__"): func = func.__wrapped__ id_func = id(func) if id_func in memo: - raise ValueError(f'wrapper loop when unwrapping {f!r}') + raise ValueError(f"wrapper loop when unwrapping {f!r}") memo.add(id_func) return func @@ -149,8 +154,7 @@ def inspect_getargspec(): func = func.im_func if not inspect.isfunction(func): if not _isCython(func): - raise TypeError('{!r} is not a Python or Cython function' - .format(func)) + raise TypeError("{!r} is not a Python or Cython function".format(func)) args, varargs, varkw = inspect.getargs(func.func_code) return inspect.ArgSpec(args, varargs, varkw, func.func_defaults) diff --git a/rhodecode/config/rcextensions/helpers/extra_fields.py b/rhodecode/config/rcextensions/helpers/extra_fields.py index 3dbf7284..6b43237d 100644 --- a/rhodecode/config/rcextensions/helpers/extra_fields.py +++ b/rhodecode/config/rcextensions/helpers/extra_fields.py @@ -43,8 +43,9 @@ example usage in hooks:: def run(*args, **kwargs): from rhodecode.model.db import Repository + # use temp name then the main one propagated - repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository'] + repo_name = kwargs.pop("REPOSITORY", None) or kwargs["repository"] repo = Repository.get_by_repo_name(repo_name) fields = {} @@ -66,13 +67,13 @@ def get_field(extra_fields_data, key, default=_Undefined(), convert_type=True): if key not in extra_fields_data: if isinstance(default, _Undefined): - raise ValueError(f'key {key} not present in extra_fields') + raise ValueError(f"key {key} not present in extra_fields") return default # NOTE(dan): from metadata we get field_label, field_value, field_desc, field_type field_metadata = extra_fields_data[key] - field_value = field_metadata['field_value'] + field_value = field_metadata["field_value"] # NOTE(dan): empty value, use default if not field_value and not isinstance(default, _Undefined): @@ -80,8 +81,8 @@ def get_field(extra_fields_data, key, default=_Undefined(), convert_type=True): if convert_type: # 'str', 'unicode', 'list', 'tuple' - _type = field_metadata['field_type'] - if _type in ['list', 'tuple']: + _type = field_metadata["field_type"] + if _type in ["list", "tuple"]: field_value = aslist(field_value) return field_value diff --git a/rhodecode/config/rcextensions/helpers/extract_post_commits.py b/rhodecode/config/rcextensions/helpers/extract_post_commits.py index 5beac048..77342f6e 100644 --- a/rhodecode/config/rcextensions/helpers/extract_post_commits.py +++ b/rhodecode/config/rcextensions/helpers/extract_post_commits.py @@ -26,6 +26,7 @@ us in hooks:: # returns list of dicts with key-val fetched from extra fields commit_list = extract_post_commits.run(**kwargs) """ + import traceback @@ -33,12 +34,12 @@ def run(*args, **kwargs): from rhodecode.lib.utils2 import extract_mentioned_users from rhodecode.model.db import Repository - commit_ids = kwargs.get('commit_ids') + commit_ids = kwargs.get("commit_ids") if not commit_ids: return 0 # use temp name then the main one propagated - repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository'] + repo_name = kwargs.pop("REPOSITORY", None) or kwargs["repository"] repo = Repository.get_by_repo_name(repo_name) commits = [] @@ -48,7 +49,7 @@ def run(*args, **kwargs): for commit_id in commit_ids: cs = vcs_repo.get_changeset(commit_id) cs_data = cs.__json__() - cs_data['mentions'] = extract_mentioned_users(cs_data['message']) + cs_data["mentions"] = extract_mentioned_users(cs_data["message"]) # optionally add more logic to parse the commits, like reading extra # fields of repository to read managers of reviewers ? commits.append(cs_data) diff --git a/rhodecode/config/rcextensions/helpers/extract_pre_commits.py b/rhodecode/config/rcextensions/helpers/extract_pre_commits.py index 589da689..bd1e3dcc 100644 --- a/rhodecode/config/rcextensions/helpers/extract_pre_commits.py +++ b/rhodecode/config/rcextensions/helpers/extract_pre_commits.py @@ -24,6 +24,7 @@ us in hooks:: commit_list = extract_pre_commits.run(**kwargs) """ + import re import collections import json @@ -39,19 +40,19 @@ def get_git_commits(repo, refs): for data in refs: # we should now extract commit data - old_rev = data['old_rev'] - new_rev = data['new_rev'] + old_rev = data["old_rev"] + new_rev = data["new_rev"] - if '00000000' in old_rev: + if "00000000" in old_rev: # new branch, we don't need to extract nothing return commits - git_env = dict(data['git_env']) + git_env = dict(data["git_env"]) # https://github.com/git/git/blob/master/Documentation/pretty-formats.txt cmd = [ - 'log', + "log", '--pretty=format:{"commit_id": "%H", "author": "%aN <%aE>", "date": "%ad", "message": "%s"}', - f'{old_rev}...{new_rev}' + f"{old_rev}...{new_rev}", ] stdout, stderr = repo.run_git_command(cmd, extra_env=git_env) @@ -60,7 +61,7 @@ def get_git_commits(repo, refs): data = json.loads(line) commits.append(data) except Exception: - print('Failed to load data from GIT line') + print("Failed to load data from GIT line") return commits @@ -68,23 +69,23 @@ def get_git_commits(repo, refs): def run(*args, **kwargs): from rhodecode.model.db import Repository - vcs_type = kwargs['scm'] + vcs_type = kwargs["scm"] # use temp name then the main one propagated - repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository'] + repo_name = kwargs.pop("REPOSITORY", None) or kwargs["repository"] repo = Repository.get_by_repo_name(repo_name) vcs_repo = repo.scm_instance(cache=False) commits = [] - if vcs_type == 'git': - for rev_data in kwargs['commit_ids']: - new_environ = {k: v for k, v in rev_data['git_env']} - commits = get_git_commits(vcs_repo, kwargs['commit_ids']) + if vcs_type == "git": + for rev_data in kwargs["commit_ids"]: + new_environ = {k: v for k, v in rev_data["git_env"]} + commits = get_git_commits(vcs_repo, kwargs["commit_ids"]) - if vcs_type == 'hg': - for rev_data in kwargs['commit_ids']: - new_environ = {k: v for k, v in rev_data['hg_env']} - commits = get_hg_commits(vcs_repo, kwargs['commit_ids']) + if vcs_type == "hg": + for rev_data in kwargs["commit_ids"]: + new_environ = {k: v for k, v in rev_data["hg_env"]} + commits = get_hg_commits(vcs_repo, kwargs["commit_ids"]) return commits diff --git a/rhodecode/config/rcextensions/helpers/extract_pre_files.py b/rhodecode/config/rcextensions/helpers/extract_pre_files.py index 0839e211..61c2b34a 100644 --- a/rhodecode/config/rcextensions/helpers/extract_pre_files.py +++ b/rhodecode/config/rcextensions/helpers/extract_pre_files.py @@ -24,6 +24,7 @@ us in hooks:: file_list = extract_pre_files.run(**kwargs) """ + import re import collections import json @@ -38,43 +39,34 @@ def get_svn_files(repo, vcs_repo, refs): txn_id = refs[0] files = [] - stdout, stderr = vcs_repo.run_svn_command( - ['svnlook', 'changed', repo.repo_full_path, '--transaction', txn_id]) + stdout, stderr = vcs_repo.run_svn_command(["svnlook", "changed", repo.repo_full_path, "--transaction", txn_id]) svn_op_to_rc_op = { - 'A': 'A', - 'U': 'M', - 'D': 'D', + "A": "A", + "U": "M", + "D": "D", } for entry in stdout.splitlines(): - parsed_entry = { - 'raw_diff': '', - 'filename': '', - 'chunks': [], - 'ops': {}, - 'file_size': 0 - } + parsed_entry = {"raw_diff": "", "filename": "", "chunks": [], "ops": {}, "file_size": 0} op = entry[0] path = entry[1:].strip() - rc_op = svn_op_to_rc_op.get(op) or '?' - parsed_entry['filename'] = path - parsed_entry['operation'] = rc_op - - if rc_op in ['A', 'M']: + rc_op = svn_op_to_rc_op.get(op) or "?" + parsed_entry["filename"] = path + parsed_entry["operation"] = rc_op + if rc_op in ["A", "M"]: stdout, stderr = vcs_repo.run_svn_command( - ['svnlook', 'filesize', repo.repo_full_path, path, '--transaction', txn_id], - _safe=True + ["svnlook", "filesize", repo.repo_full_path, path, "--transaction", txn_id], _safe=True ) - if "Path '{}' is not a file".format(path.rstrip('/')) in stderr: + if "Path '{}' is not a file".format(path.rstrip("/")) in stderr: # skip dirs continue - parsed_entry['file_size'] = safe_int(stdout.strip()) or 0 + parsed_entry["file_size"] = safe_int(stdout.strip()) or 0 files.append(parsed_entry) @@ -91,23 +83,21 @@ def get_git_files(repo, vcs_repo, refs): for data in refs: # we should now extract commit data - old_rev = data['old_rev'] - new_rev = data['new_rev'] + old_rev = data["old_rev"] + new_rev = data["new_rev"] - if '00000000' in old_rev: + if "00000000" in old_rev: # new branch, we don't need to extract nothing return files - git_env = dict(data['git_env']) + git_env = dict(data["git_env"]) - cmd = [ - 'diff', old_rev, new_rev - ] + cmd = ["diff", old_rev, new_rev] stdout, stderr = vcs_repo.run_git_command(cmd, extra_env=git_env) vcs_diff = GitDiff(stdout) - diff_processor = diffs.DiffProcessor(vcs_diff, diff_format='newdiff') + diff_processor = diffs.DiffProcessor(vcs_diff, diff_format="newdiff") # this is list of dicts with diff information # _parsed[0].keys() # ['raw_diff', 'old_revision', 'stats', 'original_filename', @@ -121,26 +111,26 @@ def get_git_files(repo, vcs_repo, refs): def run(*args, **kwargs): from rhodecode.model.db import Repository - vcs_type = kwargs['scm'] + vcs_type = kwargs["scm"] # use temp name then the main one propagated - repo_name = kwargs.pop('REPOSITORY', None) or kwargs['repository'] + repo_name = kwargs.pop("REPOSITORY", None) or kwargs["repository"] repo = Repository.get_by_repo_name(repo_name) vcs_repo = repo.scm_instance(cache=False) files = [] - if vcs_type == 'git': - for rev_data in kwargs['commit_ids']: - new_environ = {k: v for k, v in rev_data['git_env']} - files = get_git_files(repo, vcs_repo, kwargs['commit_ids']) + if vcs_type == "git": + for rev_data in kwargs["commit_ids"]: + new_environ = {k: v for k, v in rev_data["git_env"]} + files = get_git_files(repo, vcs_repo, kwargs["commit_ids"]) - if vcs_type == 'hg': - for rev_data in kwargs['commit_ids']: - new_environ = {k: v for k, v in rev_data['hg_env']} - files = get_hg_files(repo, vcs_repo, kwargs['commit_ids']) + if vcs_type == "hg": + for rev_data in kwargs["commit_ids"]: + new_environ = {k: v for k, v in rev_data["hg_env"]} + files = get_hg_files(repo, vcs_repo, kwargs["commit_ids"]) - if vcs_type == 'svn': - files = get_svn_files(repo, vcs_repo, kwargs['commit_ids']) + if vcs_type == "svn": + files = get_svn_files(repo, vcs_repo, kwargs["commit_ids"]) return files diff --git a/rhodecode/config/rcextensions/helpers/http_call.py b/rhodecode/config/rcextensions/helpers/http_call.py index cf7c2a28..2d122c0b 100644 --- a/rhodecode/config/rcextensions/helpers/http_call.py +++ b/rhodecode/config/rcextensions/helpers/http_call.py @@ -31,10 +31,10 @@ us in hooks:: from rhodecode.integrations.types.base import requests_retry_call -def run(url, json_data=None, params=None, method='post'): +def run(url, json_data=None, params=None, method="post"): requests_session = requests_retry_call() requests_session.verify = True # Verify SSL - method_caller = getattr(requests_session, method, 'post') + method_caller = getattr(requests_session, method, "post") timeout = 60 if json_data: @@ -42,7 +42,6 @@ def run(url, json_data=None, params=None, method='post'): elif params: resp = method_caller(url, params=params, timeout=timeout) else: - raise AttributeError('Provide json_data= or params= in function call') + raise AttributeError("Provide json_data= or params= in function call") resp.raise_for_status() # raise exception on a failed request return resp - diff --git a/rhodecode/config/rcextensions/hooks.py b/rhodecode/config/rcextensions/hooks.py index 72c9d501..f56cb645 100644 --- a/rhodecode/config/rcextensions/hooks.py +++ b/rhodecode/config/rcextensions/hooks.py @@ -19,124 +19,133 @@ import logging from .utils import DotDict, HookResponse, has_kwargs -log = logging.getLogger('rhodecode.' + __name__) +log = logging.getLogger("rhodecode." + __name__) # Config shortcut to keep, all configuration in one place # Example: api_key = CONFIG.my_config.api_key CONFIG = DotDict( my_config=DotDict( - api_key='', + api_key="", ), - ) -@has_kwargs({ - 'repo_name': '', - 'repo_type': '', - 'description': '', - 'private': '', - 'created_on': '', - 'enable_downloads': '', - 'repo_id': '', - 'user_id': '', - 'enable_statistics': '', - 'clone_uri': '', - 'fork_id': '', - 'group_id': '', - 'created_by': '' -}) +@has_kwargs( + { + "repo_name": "", + "repo_type": "", + "description": "", + "private": "", + "created_on": "", + "enable_downloads": "", + "repo_id": "", + "user_id": "", + "enable_statistics": "", + "clone_uri": "", + "fork_id": "", + "group_id": "", + "created_by": "", + } +) def _create_repo_hook(*args, **kwargs): """ POST CREATE REPOSITORY HOOK. This function will be executed after each repository is created. kwargs available: """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'repo_name': '', - 'repo_type': '', - 'description': '', - 'private': '', - 'created_on': '', - 'enable_downloads': '', - 'repo_id': '', - 'user_id': '', - 'enable_statistics': '', - 'clone_uri': '', - 'fork_id': '', - 'group_id': '', - 'created_by': '', - 'repository': '', - 'comment': '', - 'commit': '' -}) +@has_kwargs( + { + "repo_name": "", + "repo_type": "", + "description": "", + "private": "", + "created_on": "", + "enable_downloads": "", + "repo_id": "", + "user_id": "", + "enable_statistics": "", + "clone_uri": "", + "fork_id": "", + "group_id": "", + "created_by": "", + "repository": "", + "comment": "", + "commit": "", + } +) def _comment_commit_repo_hook(*args, **kwargs): """ POST CREATE REPOSITORY COMMENT ON COMMIT HOOK. This function will be executed after a comment is made on this repository commit. """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'repo_name': '', - 'repo_type': '', - 'description': '', - 'private': '', - 'created_on': '', - 'enable_downloads': '', - 'repo_id': '', - 'user_id': '', - 'enable_statistics': '', - 'clone_uri': '', - 'fork_id': '', - 'group_id': '', - 'created_by': '', - 'repository': '', - 'comment': '', - 'commit': '' -}) +@has_kwargs( + { + "repo_name": "", + "repo_type": "", + "description": "", + "private": "", + "created_on": "", + "enable_downloads": "", + "repo_id": "", + "user_id": "", + "enable_statistics": "", + "clone_uri": "", + "fork_id": "", + "group_id": "", + "created_by": "", + "repository": "", + "comment": "", + "commit": "", + } +) def _comment_edit_commit_repo_hook(*args, **kwargs): """ POST CREATE REPOSITORY COMMENT ON COMMIT HOOK. This function will be executed after a comment is made on this repository commit. """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'group_name': '', - 'group_parent_id': '', - 'group_description': '', - 'group_id': '', - 'user_id': '', - 'created_by': '', - 'created_on': '', - 'enable_locking': '' -}) +@has_kwargs( + { + "group_name": "", + "group_parent_id": "", + "group_description": "", + "group_id": "", + "user_id": "", + "created_by": "", + "created_on": "", + "enable_locking": "", + } +) def _create_repo_group_hook(*args, **kwargs): """ POST CREATE REPOSITORY GROUP HOOK, this function will be executed after each repository group is created. kwargs available: """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'username': '', - 'password': '', - 'email': '', - 'firstname': '', - 'lastname': '', - 'active': '', - 'admin': '', - 'created_by': '', -}) +@has_kwargs( + { + "username": "", + "password": "", + "email": "", + "firstname": "", + "lastname": "", + "active": "", + "admin": "", + "created_by": "", + } +) def _pre_create_user_hook(*args, **kwargs): """ PRE CREATE USER HOOK, this function will be executed before each @@ -148,111 +157,119 @@ def _pre_create_user_hook(*args, **kwargs): """ - reason = 'allowed' + reason = "allowed" return HookResponse(0, reason) -@has_kwargs({ - 'username': '', - 'full_name_or_username': '', - 'full_contact': '', - 'user_id': '', - 'name': '', - 'firstname': '', - 'short_contact': '', - 'admin': '', - 'lastname': '', - 'ip_addresses': '', - 'extern_type': '', - 'extern_name': '', - 'email': '', - 'api_key': '', - 'api_keys': '', - 'last_login': '', - 'full_name': '', - 'active': '', - 'password': '', - 'emails': '', - 'inherit_default_permissions': '', - 'created_by': '', - 'created_on': '', -}) +@has_kwargs( + { + "username": "", + "full_name_or_username": "", + "full_contact": "", + "user_id": "", + "name": "", + "firstname": "", + "short_contact": "", + "admin": "", + "lastname": "", + "ip_addresses": "", + "extern_type": "", + "extern_name": "", + "email": "", + "api_key": "", + "api_keys": "", + "last_login": "", + "full_name": "", + "active": "", + "password": "", + "emails": "", + "inherit_default_permissions": "", + "created_by": "", + "created_on": "", + } +) def _create_user_hook(*args, **kwargs): """ POST CREATE USER HOOK, this function will be executed after each user is created """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'repo_name': '', - 'repo_type': '', - 'description': '', - 'private': '', - 'created_on': '', - 'enable_downloads': '', - 'repo_id': '', - 'user_id': '', - 'enable_statistics': '', - 'clone_uri': '', - 'fork_id': '', - 'group_id': '', - 'deleted_by': '', - 'deleted_on': '', -}) +@has_kwargs( + { + "repo_name": "", + "repo_type": "", + "description": "", + "private": "", + "created_on": "", + "enable_downloads": "", + "repo_id": "", + "user_id": "", + "enable_statistics": "", + "clone_uri": "", + "fork_id": "", + "group_id": "", + "deleted_by": "", + "deleted_on": "", + } +) def _delete_repo_hook(*args, **kwargs): """ POST DELETE REPOSITORY HOOK, this function will be executed after each repository deletion """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'username': '', - 'full_name_or_username': '', - 'full_contact': '', - 'user_id': '', - 'name': '', - 'short_contact': '', - 'admin': '', - 'firstname': '', - 'lastname': '', - 'ip_addresses': '', - 'email': '', - 'api_key': '', - 'last_login': '', - 'full_name': '', - 'active': '', - 'password': '', - 'emails': '', - 'inherit_default_permissions': '', - 'deleted_by': '', -}) +@has_kwargs( + { + "username": "", + "full_name_or_username": "", + "full_contact": "", + "user_id": "", + "name": "", + "short_contact": "", + "admin": "", + "firstname": "", + "lastname": "", + "ip_addresses": "", + "email": "", + "api_key": "", + "last_login": "", + "full_name": "", + "active": "", + "password": "", + "emails": "", + "inherit_default_permissions": "", + "deleted_by": "", + } +) def _delete_user_hook(*args, **kwargs): """ POST DELETE USER HOOK, this function will be executed after each user is deleted kwargs available: """ - return HookResponse(0, '') + return HookResponse(0, "") # ============================================================================= # PUSH/PULL RELATED HOOKS # ============================================================================= -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'repo_store_path': 'full path to where repositories are stored', - 'commit_ids': 'pre transaction metadata for commit ids', - 'hook_type': '', - 'user_agent': 'Client user agent, e.g git or mercurial CLI version', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "repo_store_path": "full path to where repositories are stored", + "commit_ids": "pre transaction metadata for commit ids", + "hook_type": "", + "user_agent": "Client user agent, e.g git or mercurial CLI version", + } +) def _pre_push_hook(*args, **kwargs): """ Post push hook @@ -272,280 +289,298 @@ def _pre_push_hook(*args, **kwargs): u'total_commits': 2, u'type': u'branch'}] """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'repo_store_path': 'full path to where repositories are stored', - 'commit_ids': 'list of pushed commit_ids (sha1)', - 'hook_type': '', - 'user_agent': 'Client user agent, e.g git or mercurial CLI version', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "repo_store_path": "full path to where repositories are stored", + "commit_ids": "list of pushed commit_ids (sha1)", + "hook_type": "", + "user_agent": "Client user agent, e.g git or mercurial CLI version", + } +) def _push_hook(*args, **kwargs): """ POST PUSH HOOK, this function will be executed after each push it's executed after the build-in hook that RhodeCode uses for logging pushes """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'repo_store_path': 'full path to where repositories are stored', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'hook_type': '', - 'user_agent': 'Client user agent, e.g git or mercurial CLI version', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "repo_store_path": "full path to where repositories are stored", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "hook_type": "", + "user_agent": "Client user agent, e.g git or mercurial CLI version", + } +) def _pre_pull_hook(*args, **kwargs): """ Post pull hook """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'repo_store_path': 'full path to where repositories are stored', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'hook_type': '', - 'user_agent': 'Client user agent, e.g git or mercurial CLI version', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "repo_store_path": "full path to where repositories are stored", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "hook_type": "", + "user_agent": "Client user agent, e.g git or mercurial CLI version", + } +) def _pull_hook(*args, **kwargs): """ This hook will be executed after each code pull. """ - return HookResponse(0, '') + return HookResponse(0, "") # ============================================================================= # PULL REQUEST RELATED HOOKS # ============================================================================= -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'pull_request_id': '', - 'url': '', - 'title': '', - 'description': '', - 'status': '', - 'created_on': '', - 'updated_on': '', - 'commit_ids': '', - 'review_status': '', - 'mergeable': '', - 'source': '', - 'target': '', - 'author': '', - 'reviewers': '', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "pull_request_id": "", + "url": "", + "title": "", + "description": "", + "status": "", + "created_on": "", + "updated_on": "", + "commit_ids": "", + "review_status": "", + "mergeable": "", + "source": "", + "target": "", + "author": "", + "reviewers": "", + } +) def _create_pull_request_hook(*args, **kwargs): """ This hook will be executed after creation of a pull request. """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'pull_request_id': '', - 'url': '', - 'title': '', - 'description': '', - 'status': '', - 'created_on': '', - 'updated_on': '', - 'commit_ids': '', - 'review_status': '', - 'mergeable': '', - 'source': '', - 'target': '', - 'author': '', - 'reviewers': '', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "pull_request_id": "", + "url": "", + "title": "", + "description": "", + "status": "", + "created_on": "", + "updated_on": "", + "commit_ids": "", + "review_status": "", + "mergeable": "", + "source": "", + "target": "", + "author": "", + "reviewers": "", + } +) def _review_pull_request_hook(*args, **kwargs): """ This hook will be executed after review action was made on a pull request. """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - - 'action': '', - 'repository': 'repository name', - 'pull_request_id': '', - 'url': '', - 'title': '', - 'description': '', - 'status': '', - 'comment': '', - 'created_on': '', - 'updated_on': '', - 'commit_ids': '', - 'review_status': '', - 'mergeable': '', - 'source': '', - 'target': '', - 'author': '', - 'reviewers': '', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "pull_request_id": "", + "url": "", + "title": "", + "description": "", + "status": "", + "comment": "", + "created_on": "", + "updated_on": "", + "commit_ids": "", + "review_status": "", + "mergeable": "", + "source": "", + "target": "", + "author": "", + "reviewers": "", + } +) def _comment_pull_request_hook(*args, **kwargs): """ This hook will be executed after comment is made on a pull request """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - - 'action': '', - 'repository': 'repository name', - 'pull_request_id': '', - 'url': '', - 'title': '', - 'description': '', - 'status': '', - 'comment': '', - 'created_on': '', - 'updated_on': '', - 'commit_ids': '', - 'review_status': '', - 'mergeable': '', - 'source': '', - 'target': '', - 'author': '', - 'reviewers': '', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "pull_request_id": "", + "url": "", + "title": "", + "description": "", + "status": "", + "comment": "", + "created_on": "", + "updated_on": "", + "commit_ids": "", + "review_status": "", + "mergeable": "", + "source": "", + "target": "", + "author": "", + "reviewers": "", + } +) def _comment_edit_pull_request_hook(*args, **kwargs): """ This hook will be executed after comment is made on a pull request """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'pull_request_id': '', - 'url': '', - 'title': '', - 'description': '', - 'status': '', - 'created_on': '', - 'updated_on': '', - 'commit_ids': '', - 'review_status': '', - 'mergeable': '', - 'source': '', - 'target': '', - 'author': '', - 'reviewers': '', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "pull_request_id": "", + "url": "", + "title": "", + "description": "", + "status": "", + "created_on": "", + "updated_on": "", + "commit_ids": "", + "review_status": "", + "mergeable": "", + "source": "", + "target": "", + "author": "", + "reviewers": "", + } +) def _update_pull_request_hook(*args, **kwargs): """ This hook will be executed after pull requests has been updated with new commits. """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'pull_request_id': '', - 'url': '', - 'title': '', - 'description': '', - 'status': '', - 'created_on': '', - 'updated_on': '', - 'commit_ids': '', - 'review_status': '', - 'mergeable': '', - 'source': '', - 'target': '', - 'author': '', - 'reviewers': '', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "pull_request_id": "", + "url": "", + "title": "", + "description": "", + "status": "", + "created_on": "", + "updated_on": "", + "commit_ids": "", + "review_status": "", + "mergeable": "", + "source": "", + "target": "", + "author": "", + "reviewers": "", + } +) def _merge_pull_request_hook(*args, **kwargs): """ This hook will be executed after merge of a pull request. """ - return HookResponse(0, '') + return HookResponse(0, "") -@has_kwargs({ - 'server_url': 'url of instance that triggered this hook', - 'config': 'path to .ini config used', - 'scm': 'type of version control "git", "hg", "svn"', - 'username': 'username of actor who triggered this event', - 'ip': 'ip address of actor who triggered this hook', - 'action': '', - 'repository': 'repository name', - 'pull_request_id': '', - 'url': '', - 'title': '', - 'description': '', - 'status': '', - 'created_on': '', - 'updated_on': '', - 'commit_ids': '', - 'review_status': '', - 'mergeable': '', - 'source': '', - 'target': '', - 'author': '', - 'reviewers': '', -}) +@has_kwargs( + { + "server_url": "url of instance that triggered this hook", + "config": "path to .ini config used", + "scm": 'type of version control "git", "hg", "svn"', + "username": "username of actor who triggered this event", + "ip": "ip address of actor who triggered this hook", + "action": "", + "repository": "repository name", + "pull_request_id": "", + "url": "", + "title": "", + "description": "", + "status": "", + "created_on": "", + "updated_on": "", + "commit_ids": "", + "review_status": "", + "mergeable": "", + "source": "", + "target": "", + "author": "", + "reviewers": "", + } +) def _close_pull_request_hook(*args, **kwargs): """ This hook will be executed after close of a pull request. """ - return HookResponse(0, '') + return HookResponse(0, "") diff --git a/rhodecode/config/rcextensions/mapping.py b/rhodecode/config/rcextensions/mapping.py index 4fcbb6fe..01fb55ea 100644 --- a/rhodecode/config/rcextensions/mapping.py +++ b/rhodecode/config/rcextensions/mapping.py @@ -8,7 +8,7 @@ # more than one name for extension # NOTE: that this will override any mappings in LANGUAGES_EXTENSIONS_MAP # build by pygments -EXTRA_MAPPINGS = {'html': ['Text']} +EXTRA_MAPPINGS = {"html": ["Text"]} # additional lexer definitions for custom files it's overrides pygments lexers, # and uses defined name of lexer to colorize the files. Format is {'ext': @@ -16,6 +16,4 @@ EXTRA_MAPPINGS = {'html': ['Text']} # >> python -c "import pprint;from pygments import lexers; # pprint.pprint([(x[0], x[1]) for x in lexers.get_all_lexers()]);" -EXTRA_LEXERS = { - 'tt': 'vbnet' -} +EXTRA_LEXERS = {"tt": "vbnet"} diff --git a/rhodecode/config/rcextensions/utils.py b/rhodecode/config/rcextensions/utils.py index 31f2e27f..c5e46320 100644 --- a/rhodecode/config/rcextensions/utils.py +++ b/rhodecode/config/rcextensions/utils.py @@ -25,7 +25,7 @@ import urllib.request import urllib.parse import urllib.error -log = logging.getLogger('rhodecode.' + __name__) +log = logging.getLogger("rhodecode." + __name__) class HookResponse: @@ -34,9 +34,9 @@ class HookResponse: self.output = output def __add__(self, other): - other_status = getattr(other, 'status', 0) + other_status = getattr(other, "status", 0) new_status = max(self.status, other_status) - other_output = getattr(other, 'output', '') + other_output = getattr(other, "output", "") new_output = self.output + other_output return HookResponse(new_status, new_output) @@ -45,13 +45,13 @@ class HookResponse: return self.status == 0 def to_json(self): - return {'status': self.status, 'output': self.output} + return {"status": self.status, "output": self.output} def __repr__(self): return self.to_json().__repr__() -class DotDict(dict): +class DotDict(dict): def __contains__(self, k): try: return dict.__contains__(self, k) or hasattr(self, k) @@ -96,8 +96,8 @@ class DotDict(dict): def __repr__(self): keys = list(self.keys()) keys.sort() - args = ', '.join(['{}={!r}'.format(key, self[key]) for key in keys]) - return '{}({})'.format(self.__class__.__name__, args) + args = ", ".join(["{}={!r}".format(key, self[key]) for key in keys]) + return "{}({})".format(self.__class__.__name__, args) @staticmethod def fromDict(d): @@ -132,8 +132,9 @@ def _verify_kwargs(func_name, expected_parameters, kwargs): missing_kwargs = expected_parameters - kwargs_keys unexpected_kwargs = kwargs_keys - expected_parameters raise AssertionError( - "func:%s: missing parameters: %r, unexpected parameters: %s" % - (func_name, missing_kwargs, unexpected_kwargs)) + "func:%s: missing parameters: %r, unexpected parameters: %s" + % (func_name, missing_kwargs, unexpected_kwargs) + ) def has_kwargs(required_args): @@ -142,20 +143,24 @@ def has_kwargs(required_args): :param required_args: """ + def wrap(func): def wrapper(*args, **kwargs): _verify_kwargs(func.__name__, required_args.keys(), kwargs) # in case there's `calls` defined on module we store the data maybe_log_call(func.__name__, args, kwargs) - log.debug('Calling rcextensions function %s', func.__name__) + log.debug("Calling rcextensions function %s", func.__name__) return func(*args, **kwargs) + return wrapper + return wrap def maybe_log_call(name, args, kwargs): from rhodecode.config import rcextensions - if hasattr(rcextensions, 'calls'): + + if hasattr(rcextensions, "calls"): calls = rcextensions.calls calls[name].append((args, kwargs)) @@ -174,7 +179,7 @@ def str2bool(_str) -> bool: if _str in (True, False): return _str _str = str(_str).strip().lower() - return _str in ('t', 'true', 'y', 'yes', 'on', '1') + return _str in ("t", "true", "y", "yes", "on", "1") def aslist(obj, sep=None, strip=True): @@ -199,7 +204,6 @@ def aslist(obj, sep=None, strip=True): class UrlTemplate(string.Template): - def safe_substitute(self, **kws): # url encode the kw for usage in url kws = {k: urllib.parse.quote(str(v)) for k, v in kws.items()} diff --git a/rhodecode/config/routing_links.py b/rhodecode/config/routing_links.py index 3e45ff6c..b8271299 100644 --- a/rhodecode/config/routing_links.py +++ b/rhodecode/config/routing_links.py @@ -43,7 +43,6 @@ you can see it working. """ # pragma: no cover - link_config = [ { "name": "enterprise_docs", @@ -95,10 +94,9 @@ link_config = [ "target": "https://rhodecode.com/translate/enterprise", "external_target": "https://explore.transifex.com/rhodecode/RhodeCode/", }, - ] def connect_redirection_links(config): for link in link_config: - config.add_route(link['name'], link['target'], static=True) + config.add_route(link["name"], link["target"], static=True) diff --git a/rhodecode/config/settings_maker.py b/rhodecode/config/settings_maker.py index 100f1505..4bca59d2 100644 --- a/rhodecode/config/settings_maker.py +++ b/rhodecode/config/settings_maker.py @@ -30,13 +30,10 @@ log = logging.getLogger(__name__) # skip keys, that are set here, so we don't double process those -set_keys = { - '__file__': '' -} +set_keys = {"__file__": ""} class SettingsMaker: - def __init__(self, app_settings): self.settings = app_settings @@ -44,7 +41,7 @@ class SettingsMaker: def _bool_func(cls, input_val): if isinstance(input_val, bytes): # decode to str - input_val = input_val.decode('utf8') + input_val = input_val.decode("utf8") return str2bool(input_val) @classmethod @@ -56,7 +53,7 @@ class SettingsMaker: return float(input_val) @classmethod - def _list_func(cls, input_val, sep=','): + def _list_func(cls, input_val, sep=","): return aslist(input_val, sep=sep) @classmethod @@ -76,17 +73,16 @@ class SettingsMaker: input_val = cls._string_func(input_val, lower=lower) if input_val in ['""', "''"]: - return '' + return "" @classmethod def _dir_func(cls, input_val, ensure_dir=False, mode=0o755): - # ensure we have our dir created if not os.path.isdir(input_val) and ensure_dir: os.makedirs(input_val, mode=mode, exist_ok=True) if not os.path.isdir(input_val): - raise Exception(f'Dir at {input_val} does not exist') + raise Exception(f"Dir at {input_val} does not exist") return input_val @classmethod @@ -97,19 +93,19 @@ class SettingsMaker: @classmethod def _key_transformator(cls, key): - return "{}_{}".format('RC'.upper(), key.upper().replace('.', '_').replace('-', '_')) + return "{}_{}".format("RC".upper(), key.upper().replace(".", "_").replace("-", "_")) def maybe_env_key(self, key): # now maybe we have this KEY in env, search and use the value with higher priority. transformed_key = self._key_transformator(key) envvar_value = os.environ.get(transformed_key) if envvar_value: - log.debug('using `%s` key instead of `%s` key for config', transformed_key, key) + log.debug("using `%s` key instead of `%s` key for config", transformed_key, key) return envvar_value def env_expand(self): - if self.settings.get('rhodecode.env_expand') == 'false': + if self.settings.get("rhodecode.env_expand") == "false": return replaced = {} @@ -123,33 +119,36 @@ class SettingsMaker: # replace ALL keys updated self.settings.update(replaced) - def enable_logging(self, logging_conf=None, level='INFO', formatter='generic'): + def enable_logging(self, logging_conf=None, level="INFO", formatter="generic"): """ Helper to enable debug on running instance :return: """ - if not str2bool(self.settings.get('logging.autoconfigure')): - log.info('logging configuration based on main .ini file') + if not str2bool(self.settings.get("logging.autoconfigure")): + log.info("logging configuration based on main .ini file") return if logging_conf is None: - logging_conf = self.settings.get('logging.logging_conf_file') or '' + logging_conf = self.settings.get("logging.logging_conf_file") or "" if not os.path.isfile(logging_conf): - log.error('Unable to setup logging based on %s, ' - 'file does not exist.... specify path using logging.logging_conf_file= config setting. ', logging_conf) + log.error( + "Unable to setup logging based on %s, " + "file does not exist.... specify path using logging.logging_conf_file= config setting. ", + logging_conf, + ) return - with open(logging_conf, 'rt') as f: + with open(logging_conf, "rt") as f: ini_template = textwrap.dedent(f.read()) ini_template = string.Template(ini_template).safe_substitute( - RC_LOGGING_LEVEL=os.environ.get('RC_LOGGING_LEVEL', '') or level, - RC_LOGGING_FORMATTER=os.environ.get('RC_LOGGING_FORMATTER', '') or formatter + RC_LOGGING_LEVEL=os.environ.get("RC_LOGGING_LEVEL", "") or level, + RC_LOGGING_FORMATTER=os.environ.get("RC_LOGGING_FORMATTER", "") or formatter, ) - with tempfile.NamedTemporaryFile(prefix='rc_logging_', suffix='.ini', delete=False) as f: - log.info('Saved Temporary LOGGING config at %s', f.name) + with tempfile.NamedTemporaryFile(prefix="rc_logging_", suffix=".ini", delete=False) as f: + log.info("Saved Temporary LOGGING config at %s", f.name) f.write(ini_template) logging.config.fileConfig(f.name) @@ -163,19 +162,19 @@ class SettingsMaker: input_val = default parser_func = { - 'bool': self._bool_func, - 'int': self._int_func, - 'float': self._float_func, - 'list': self._list_func, - 'list:newline': functools.partial(self._list_func, sep='/n'), - 'list:spacesep': functools.partial(self._list_func, sep=' '), - 'string': functools.partial(self._string_func, lower=lower), - 'string:noquote': functools.partial(self._string_no_quote_func, lower=lower), - 'dir': self._dir_func, - 'dir:ensured': functools.partial(self._dir_func, ensure_dir=True), - 'file': self._file_path_func, - 'file:ensured': functools.partial(self._file_path_func, ensure_dir=True), - None: lambda i: i + "bool": self._bool_func, + "int": self._int_func, + "float": self._float_func, + "list": self._list_func, + "list:newline": functools.partial(self._list_func, sep="/n"), + "list:spacesep": functools.partial(self._list_func, sep=" "), + "string": functools.partial(self._string_func, lower=lower), + "string:noquote": functools.partial(self._string_no_quote_func, lower=lower), + "dir": self._dir_func, + "dir:ensured": functools.partial(self._dir_func, ensure_dir=True), + "file": self._file_path_func, + "file:ensured": functools.partial(self._file_path_func, ensure_dir=True), + None: lambda i: i, }[parser] envvar_value = self.maybe_env_key(key) diff --git a/rhodecode/config/utils.py b/rhodecode/config/utils.py index c2d1fbf8..e3ceb825 100644 --- a/rhodecode/config/utils.py +++ b/rhodecode/config/utils.py @@ -21,7 +21,7 @@ import platform from rhodecode.lib.type_utils import str2bool -DEFAULT_USER = 'default' +DEFAULT_USER = "default" def configure_vcs(config): @@ -32,33 +32,38 @@ def configure_vcs(config): import rhodecode.lib.vcs.conf.settings conf.settings.BACKENDS = { - 'hg': 'rhodecode.lib.vcs.backends.hg.MercurialRepository', - 'git': 'rhodecode.lib.vcs.backends.git.GitRepository', - 'svn': 'rhodecode.lib.vcs.backends.svn.SubversionRepository', + "hg": "rhodecode.lib.vcs.backends.hg.MercurialRepository", + "git": "rhodecode.lib.vcs.backends.git.GitRepository", + "svn": "rhodecode.lib.vcs.backends.svn.SubversionRepository", } - conf.settings.HOOKS_PROTOCOL = config['vcs.hooks.protocol.v2'] - conf.settings.HOOKS_HOST = config['vcs.hooks.host'] - conf.settings.ALIASES[:] = config['vcs.backends'] - conf.settings.SVN_COMPATIBLE_VERSION = config['vcs.svn.compatible_version'] + conf.settings.HOOKS_PROTOCOL = config["vcs.hooks.protocol.v2"] + conf.settings.HOOKS_HOST = config["vcs.hooks.host"] + conf.settings.ALIASES[:] = config["vcs.backends"] + conf.settings.SVN_COMPATIBLE_VERSION = config["vcs.svn.compatible_version"] def initialize_database(config): from rhodecode.lib.utils2 import engine_from_config, get_encryption_key from rhodecode.model import init_model - engine = engine_from_config(config, 'sqlalchemy.db1.') + + engine = engine_from_config(config, "sqlalchemy.db1.") init_model(engine, encryption_key=get_encryption_key(config)) + def initialize_test_environment(settings): - skip_test_env = str2bool(os.environ.get('RC_NO_TEST_ENV')) + skip_test_env = str2bool(os.environ.get("RC_NO_TEST_ENV")) if skip_test_env: return - repo_store_path = os.environ.get('RC_TEST_ENV_REPO_STORE') or settings['repo_store.path'] + repo_store_path = os.environ.get("RC_TEST_ENV_REPO_STORE") or settings["repo_store.path"] from rhodecode.lib.utils import ( - create_test_directory, create_test_database, create_test_repositories, - create_test_index) + create_test_directory, + create_test_database, + create_test_repositories, + create_test_index, + ) create_test_directory(repo_store_path) @@ -69,7 +74,7 @@ def initialize_test_environment(settings): def get_vcs_server_protocol(config): - return config['vcs.server.protocol'] + return config["vcs.server.protocol"] def set_instance_id(config): @@ -78,15 +83,14 @@ def set_instance_id(config): E.g instance_id = *cluster-1 or instance_id = * """ - config['instance_id'] = config.get('instance_id') or '' - instance_id = config['instance_id'] - if instance_id.startswith('*') or not instance_id: - prefix = instance_id.lstrip('*') - _platform_id = platform.uname()[1] or 'instance' - config['instance_id'] = '{prefix}uname:{platform}-pid:{pid}'.format( - prefix=prefix, - platform=_platform_id, - pid=os.getpid()) + config["instance_id"] = config.get("instance_id") or "" + instance_id = config["instance_id"] + if instance_id.startswith("*") or not instance_id: + prefix = instance_id.lstrip("*") + _platform_id = platform.uname()[1] or "instance" + config["instance_id"] = "{prefix}uname:{platform}-pid:{pid}".format( + prefix=prefix, platform=_platform_id, pid=os.getpid() + ) def get_default_user_id(): @@ -95,12 +99,10 @@ def get_default_user_id(): engine = meta.get_engine() with meta.SA_Session(engine) as session: - result = session.execute(text( - "SELECT user_id from users where username = :uname" - ), {'uname': DEFAULT_USER}) + result = session.execute(text("SELECT user_id from users where username = :uname"), {"uname": DEFAULT_USER}) user = result.first() if not user: - raise ValueError('Unable to retrieve default user data from DB') + raise ValueError("Unable to retrieve default user data from DB") user_id = user[0] return user_id diff --git a/rhodecode/events/pullrequest.py b/rhodecode/events/pullrequest.py index 9551e0a8..6cbddaab 100644 --- a/rhodecode/events/pullrequest.py +++ b/rhodecode/events/pullrequest.py @@ -206,7 +206,7 @@ class PullRequestCommentEditEvent(PullRequestEvent): "url": CommentsModel().get_url(self.comment, request=self.request), "permalink_url": CommentsModel().get_url(self.comment, request=self.request, permalink=True), }, - "context": self.context + "context": self.context, } ) return data diff --git a/rhodecode/events/repo.py b/rhodecode/events/repo.py index 757d0a2f..c0310439 100644 --- a/rhodecode/events/repo.py +++ b/rhodecode/events/repo.py @@ -125,7 +125,7 @@ def _commits_as_dict(event, commit_ids, repos): missing_commits = set(commit_ids) - set(c["raw_id"] for c in commits) if missing_commits: - log.error("Inconsistent repository state. " "Missing commits: %s", ", ".join(missing_commits)) + log.error("Inconsistent repository state. Missing commits: %s", ", ".join(missing_commits)) return commits diff --git a/rhodecode/events/repo_group.py b/rhodecode/events/repo_group.py index 9b28c937..8856353c 100644 --- a/rhodecode/events/repo_group.py +++ b/rhodecode/events/repo_group.py @@ -51,7 +51,7 @@ class RepoGroupEvent(RhodeCodeIntegrationEvent): "created_on": self.repo_group.created_on, "enable_locking": self.repo_group.enable_locking, }, - "context": self.context + "context": self.context, } ) return data diff --git a/rhodecode/forms/__init__.py b/rhodecode/forms/__init__.py index 9f04ea30..4ca01667 100644 --- a/rhodecode/forms/__init__.py +++ b/rhodecode/forms/__init__.py @@ -29,19 +29,18 @@ from deform import Button, Form, widget, ValidationFailure class buttons: - save = Button(name='Save', type='submit') - reset = Button(name=_('Reset'), type='reset') - delete = Button(name=_('Delete'), type='submit') + save = Button(name="Save", type="submit") + reset = Button(name=_("Reset"), type="reset") + delete = Button(name=_("Delete"), type="submit") class RcForm(Form): def render_error(self, request, field): - html = '' + html = "" if field.error: for err in field.error.messages(): if isinstance(err, TranslationString): err = request.translate(err) - html = Template( - '${err}').render(err=err) + html = Template('${err}').render(err=err) return html diff --git a/rhodecode/integrations/__init__.py b/rhodecode/integrations/__init__.py index b1a75eb3..80f5c8ab 100644 --- a/rhodecode/integrations/__init__.py +++ b/rhodecode/integrations/__init__.py @@ -30,21 +30,15 @@ log = logging.getLogger(__name__) # includeme level later to allow per instance integration setup integration_type_registry = IntegrationTypeRegistry() -integration_type_registry.register_integration_type( - webhook.WebhookIntegrationType) -integration_type_registry.register_integration_type( - slack.SlackIntegrationType) -integration_type_registry.register_integration_type( - email.EmailIntegrationType) +integration_type_registry.register_integration_type(webhook.WebhookIntegrationType) +integration_type_registry.register_integration_type(slack.SlackIntegrationType) +integration_type_registry.register_integration_type(email.EmailIntegrationType) # dummy EE integration to show users what we have in EE edition -integration_type_registry.register_integration_type( - base.EEIntegration('Jira Issues integration', 'jira')) -integration_type_registry.register_integration_type( - base.EEIntegration('Redmine Tracker integration', 'redmine')) -integration_type_registry.register_integration_type( - base.EEIntegration('Jenkins CI integration', 'jenkins')) +integration_type_registry.register_integration_type(base.EEIntegration("Jira Issues integration", "jira")) +integration_type_registry.register_integration_type(base.EEIntegration("Redmine Tracker integration", "redmine")) +integration_type_registry.register_integration_type(base.EEIntegration("Jenkins CI integration", "jenkins")) def integrations_event_handler(event): @@ -61,10 +55,8 @@ def integrations_event_handler(event): except Exception: exc_info = sys.exc_info() store_exception(id(exc_info), exc_info) - log.exception( - 'failure occurred when sending event %s to integration %s', - event, integration) + log.exception("failure occurred when sending event %s to integration %s", event, integration) def includeme(config): - config.include('rhodecode.integrations.routes') + config.include("rhodecode.integrations.routes") diff --git a/rhodecode/integrations/registry.py b/rhodecode/integrations/registry.py index 8d408d7a..5ad1a31d 100644 --- a/rhodecode/integrations/registry.py +++ b/rhodecode/integrations/registry.py @@ -26,11 +26,10 @@ class IntegrationTypeRegistry(collections.OrderedDict): """ Registry Class to hold IntegrationTypes """ + def register_integration_type(self, IntegrationType): key = IntegrationType.key if key in self: - log.debug( - 'Overriding existing integration type %s (%s) with %s', - self[key].__class__, key, IntegrationType) + log.debug("Overriding existing integration type %s (%s) with %s", self[key].__class__, key, IntegrationType) self[key] = IntegrationType diff --git a/rhodecode/integrations/routes.py b/rhodecode/integrations/routes.py index 7173bf49..b183546e 100644 --- a/rhodecode/integrations/routes.py +++ b/rhodecode/integrations/routes.py @@ -34,13 +34,13 @@ class ValidIntegrationPredicate(object): self.val = val def text(self): - return f'valid_integration_route = {self.val}' + return f"valid_integration_route = {self.val}" phash = text def __call__(self, info, request): - integration_type = info['match']['integration'] - integration_id = info['match'].get('integration_id') + integration_type = info["match"]["integration"] + integration_id = info["match"].get("integration_id") if integration_type not in integration_type_registry: return False @@ -56,8 +56,8 @@ class ValidIntegrationPredicate(object): return False # match types to repo or repo group - repo_name = info['match'].get('repo_name') - repo_group_name = info['match'].get('repo_group_name') + repo_name = info["match"].get("repo_name") + repo_group_name = info["match"].get("repo_group_name") repo, repo_group = None, None if repo_name: repo = Repository.get_by_repo_name(repo_name) @@ -78,164 +78,214 @@ class ValidIntegrationPredicate(object): def includeme(config): - config.add_route_predicate( - 'valid_integration', ValidIntegrationPredicate) + config.add_route_predicate("valid_integration", ValidIntegrationPredicate) # global integrations - config.add_route('global_integrations_new', - ADMIN_PREFIX + '/integrations/new') - config.add_view(GlobalIntegrationsView, - attr='new_integration', - renderer='rhodecode:templates/admin/integrations/new.mako', - request_method='GET', - route_name='global_integrations_new') + config.add_route("global_integrations_new", ADMIN_PREFIX + "/integrations/new") + config.add_view( + GlobalIntegrationsView, + attr="new_integration", + renderer="rhodecode:templates/admin/integrations/new.mako", + request_method="GET", + route_name="global_integrations_new", + ) - config.add_route('global_integrations_home', - ADMIN_PREFIX + '/integrations') - config.add_route('global_integrations_list', - ADMIN_PREFIX + '/integrations/{integration}') - for route_name in ['global_integrations_home', 'global_integrations_list']: - config.add_view(GlobalIntegrationsView, - attr='integration_list', - renderer='rhodecode:templates/admin/integrations/list.mako', - request_method='GET', - route_name=route_name) + config.add_route("global_integrations_home", ADMIN_PREFIX + "/integrations") + config.add_route("global_integrations_list", ADMIN_PREFIX + "/integrations/{integration}") + for route_name in ["global_integrations_home", "global_integrations_list"]: + config.add_view( + GlobalIntegrationsView, + attr="integration_list", + renderer="rhodecode:templates/admin/integrations/list.mako", + request_method="GET", + route_name=route_name, + ) - config.add_route('global_integrations_create', - ADMIN_PREFIX + '/integrations/{integration}/new', - valid_integration=True) - config.add_route('global_integrations_edit', - ADMIN_PREFIX + '/integrations/{integration}/{integration_id}', - valid_integration=True) + config.add_route( + "global_integrations_create", ADMIN_PREFIX + "/integrations/{integration}/new", valid_integration=True + ) + config.add_route( + "global_integrations_edit", + ADMIN_PREFIX + "/integrations/{integration}/{integration_id}", + valid_integration=True, + ) - for route_name in ['global_integrations_create', 'global_integrations_edit']: - config.add_view(GlobalIntegrationsView, - attr='settings_get', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='GET', - route_name=route_name) - config.add_view(GlobalIntegrationsView, - attr='settings_post', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='POST', - route_name=route_name) + for route_name in ["global_integrations_create", "global_integrations_edit"]: + config.add_view( + GlobalIntegrationsView, + attr="settings_get", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="GET", + route_name=route_name, + ) + config.add_view( + GlobalIntegrationsView, + attr="settings_post", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="POST", + route_name=route_name, + ) # repo group integrations - config.add_route('repo_group_integrations_home', - add_route_requirements('/{repo_group_name}/_settings/integrations'), - repo_group_route=True) + config.add_route( + "repo_group_integrations_home", + add_route_requirements("/{repo_group_name}/_settings/integrations"), + repo_group_route=True, + ) - config.add_view(RepoGroupIntegrationsView, - attr='integration_list', - renderer='rhodecode:templates/admin/integrations/list.mako', - request_method='GET', - route_name='repo_group_integrations_home') + config.add_view( + RepoGroupIntegrationsView, + attr="integration_list", + renderer="rhodecode:templates/admin/integrations/list.mako", + request_method="GET", + route_name="repo_group_integrations_home", + ) - config.add_route('repo_group_integrations_new', - add_route_requirements('/{repo_group_name}/_settings/integrations/new'), - repo_group_route=True) - config.add_view(RepoGroupIntegrationsView, - attr='new_integration', - renderer='rhodecode:templates/admin/integrations/new.mako', - request_method='GET', - route_name='repo_group_integrations_new') + config.add_route( + "repo_group_integrations_new", + add_route_requirements("/{repo_group_name}/_settings/integrations/new"), + repo_group_route=True, + ) + config.add_view( + RepoGroupIntegrationsView, + attr="new_integration", + renderer="rhodecode:templates/admin/integrations/new.mako", + request_method="GET", + route_name="repo_group_integrations_new", + ) - config.add_route('repo_group_integrations_list', - add_route_requirements('/{repo_group_name}/_settings/integrations/{integration}'), - repo_group_route=True, - valid_integration=True) - config.add_view(RepoGroupIntegrationsView, - attr='integration_list', - renderer='rhodecode:templates/admin/integrations/list.mako', - request_method='GET', - route_name='repo_group_integrations_list') + config.add_route( + "repo_group_integrations_list", + add_route_requirements("/{repo_group_name}/_settings/integrations/{integration}"), + repo_group_route=True, + valid_integration=True, + ) + config.add_view( + RepoGroupIntegrationsView, + attr="integration_list", + renderer="rhodecode:templates/admin/integrations/list.mako", + request_method="GET", + route_name="repo_group_integrations_list", + ) - config.add_route('repo_group_integrations_create', - add_route_requirements('/{repo_group_name}/_settings/integrations/{integration}/new'), - repo_group_route=True, - valid_integration=True) - config.add_view(RepoGroupIntegrationsView, - attr='settings_get', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='GET', - route_name='repo_group_integrations_create') - config.add_view(RepoGroupIntegrationsView, - attr='settings_post', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='POST', - route_name='repo_group_integrations_create') + config.add_route( + "repo_group_integrations_create", + add_route_requirements("/{repo_group_name}/_settings/integrations/{integration}/new"), + repo_group_route=True, + valid_integration=True, + ) + config.add_view( + RepoGroupIntegrationsView, + attr="settings_get", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="GET", + route_name="repo_group_integrations_create", + ) + config.add_view( + RepoGroupIntegrationsView, + attr="settings_post", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="POST", + route_name="repo_group_integrations_create", + ) - config.add_route('repo_group_integrations_edit', - add_route_requirements('/{repo_group_name}/_settings/integrations/{integration}/{integration_id}'), - repo_group_route=True, - valid_integration=True) + config.add_route( + "repo_group_integrations_edit", + add_route_requirements("/{repo_group_name}/_settings/integrations/{integration}/{integration_id}"), + repo_group_route=True, + valid_integration=True, + ) - config.add_view(RepoGroupIntegrationsView, - attr='settings_get', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='GET', - route_name='repo_group_integrations_edit') - config.add_view(RepoGroupIntegrationsView, - attr='settings_post', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='POST', - route_name='repo_group_integrations_edit') + config.add_view( + RepoGroupIntegrationsView, + attr="settings_get", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="GET", + route_name="repo_group_integrations_edit", + ) + config.add_view( + RepoGroupIntegrationsView, + attr="settings_post", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="POST", + route_name="repo_group_integrations_edit", + ) # repo integrations - config.add_route('repo_integrations_home', - add_route_requirements('/{repo_name}/settings/integrations'), - repo_route=True) - config.add_view(RepoIntegrationsView, - attr='integration_list', - request_method='GET', - renderer='rhodecode:templates/admin/integrations/list.mako', - route_name='repo_integrations_home') + config.add_route( + "repo_integrations_home", add_route_requirements("/{repo_name}/settings/integrations"), repo_route=True + ) + config.add_view( + RepoIntegrationsView, + attr="integration_list", + request_method="GET", + renderer="rhodecode:templates/admin/integrations/list.mako", + route_name="repo_integrations_home", + ) - config.add_route('repo_integrations_new', - add_route_requirements('/{repo_name}/settings/integrations/new'), - repo_route=True) - config.add_view(RepoIntegrationsView, - attr='new_integration', - renderer='rhodecode:templates/admin/integrations/new.mako', - request_method='GET', - route_name='repo_integrations_new') + config.add_route( + "repo_integrations_new", add_route_requirements("/{repo_name}/settings/integrations/new"), repo_route=True + ) + config.add_view( + RepoIntegrationsView, + attr="new_integration", + renderer="rhodecode:templates/admin/integrations/new.mako", + request_method="GET", + route_name="repo_integrations_new", + ) - config.add_route('repo_integrations_list', - add_route_requirements('/{repo_name}/settings/integrations/{integration}'), - repo_route=True, - valid_integration=True) - config.add_view(RepoIntegrationsView, - attr='integration_list', - request_method='GET', - renderer='rhodecode:templates/admin/integrations/list.mako', - route_name='repo_integrations_list') + config.add_route( + "repo_integrations_list", + add_route_requirements("/{repo_name}/settings/integrations/{integration}"), + repo_route=True, + valid_integration=True, + ) + config.add_view( + RepoIntegrationsView, + attr="integration_list", + request_method="GET", + renderer="rhodecode:templates/admin/integrations/list.mako", + route_name="repo_integrations_list", + ) - config.add_route('repo_integrations_create', - add_route_requirements('/{repo_name}/settings/integrations/{integration}/new'), - repo_route=True, - valid_integration=True) - config.add_view(RepoIntegrationsView, - attr='settings_get', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='GET', - route_name='repo_integrations_create') - config.add_view(RepoIntegrationsView, - attr='settings_post', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='POST', - route_name='repo_integrations_create') + config.add_route( + "repo_integrations_create", + add_route_requirements("/{repo_name}/settings/integrations/{integration}/new"), + repo_route=True, + valid_integration=True, + ) + config.add_view( + RepoIntegrationsView, + attr="settings_get", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="GET", + route_name="repo_integrations_create", + ) + config.add_view( + RepoIntegrationsView, + attr="settings_post", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="POST", + route_name="repo_integrations_create", + ) - config.add_route('repo_integrations_edit', - add_route_requirements('/{repo_name}/settings/integrations/{integration}/{integration_id}'), - repo_route=True, - valid_integration=True) - config.add_view(RepoIntegrationsView, - attr='settings_get', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='GET', - route_name='repo_integrations_edit') - config.add_view(RepoIntegrationsView, - attr='settings_post', - renderer='rhodecode:templates/admin/integrations/form.mako', - request_method='POST', - route_name='repo_integrations_edit') + config.add_route( + "repo_integrations_edit", + add_route_requirements("/{repo_name}/settings/integrations/{integration}/{integration_id}"), + repo_route=True, + valid_integration=True, + ) + config.add_view( + RepoIntegrationsView, + attr="settings_get", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="GET", + route_name="repo_integrations_edit", + ) + config.add_view( + RepoIntegrationsView, + attr="settings_post", + renderer="rhodecode:templates/admin/integrations/form.mako", + request_method="POST", + route_name="repo_integrations_edit", + ) diff --git a/rhodecode/integrations/schema.py b/rhodecode/integrations/schema.py index 38a9de3e..26f69359 100644 --- a/rhodecode/integrations/schema.py +++ b/rhodecode/integrations/schema.py @@ -25,16 +25,16 @@ class IntegrationOptionsSchemaBase(colander.MappingSchema): enabled = colander.SchemaNode( colander.Bool(), default=True, - description=_('Enable or disable this integration.'), + description=_("Enable or disable this integration."), missing=False, - title=_('Enabled'), + title=_("Enabled"), ) name = colander.SchemaNode( colander.String(), - description=_('Short name for this integration.'), + description=_("Short name for this integration."), missing=colander.required, - title=_('Integration name'), + title=_("Integration name"), ) @@ -47,10 +47,11 @@ class RepoGroupIntegrationOptionsSchema(IntegrationOptionsSchemaBase): colander.Bool(), default=True, description=_( - 'Limit integrations to to work only on the direct children ' - 'repositories of this repository group (no subgroups)'), + "Limit integrations to to work only on the direct children " + "repositories of this repository group (no subgroups)" + ), missing=False, - title=_('Limit to childen repos only'), + title=_("Limit to childen repos only"), ) @@ -58,10 +59,9 @@ class GlobalIntegrationOptionsSchema(IntegrationOptionsSchemaBase): child_repos_only = colander.SchemaNode( colander.Bool(), default=False, - description=_( - 'Limit integrations to to work only on root level repositories'), + description=_("Limit integrations to to work only on root level repositories"), missing=False, - title=_('Root repositories only'), + title=_("Root repositories only"), ) diff --git a/rhodecode/integrations/tests/test_integrations.py b/rhodecode/integrations/tests/test_integrations.py index a11bb87a..2763eb26 100644 --- a/rhodecode/integrations/tests/test_integrations.py +++ b/rhodecode/integrations/tests/test_integrations.py @@ -25,8 +25,7 @@ from rhodecode.integrations import integration_type_registry from rhodecode.tests.routes import route_path -def _post_integration_test_helper(app, url, csrf_token, repo, repo_group, - admin_view): +def _post_integration_test_helper(app, url, csrf_token, repo, repo_group, admin_view): """ Posts form data to create integration at the url given then deletes it and checks if the redirect url is correct. @@ -34,193 +33,170 @@ def _post_integration_test_helper(app, url, csrf_token, repo, repo_group, repo_name = repo.repo_name repo_group_name = repo_group.group_name app.post(url, params={}, status=403) # missing csrf check - response = app.post(url, params={'csrf_token': csrf_token}) + response = app.post(url, params={"csrf_token": csrf_token}) assert response.status_code == 200 - response.mustcontain('Errors exist') + response.mustcontain("Errors exist") scopes_destinations = [ - ('global', - ADMIN_PREFIX + '/integrations'), - ('root-repos', - ADMIN_PREFIX + '/integrations'), - ('repo:%s' % repo_name, - '/%s/settings/integrations' % repo_name), - ('repogroup:%s' % repo_group_name, - '/%s/_settings/integrations' % repo_group_name), - ('repogroup-recursive:%s' % repo_group_name, - '/%s/_settings/integrations' % repo_group_name), + ("global", ADMIN_PREFIX + "/integrations"), + ("root-repos", ADMIN_PREFIX + "/integrations"), + ("repo:%s" % repo_name, "/%s/settings/integrations" % repo_name), + ("repogroup:%s" % repo_group_name, "/%s/_settings/integrations" % repo_group_name), + ("repogroup-recursive:%s" % repo_group_name, "/%s/_settings/integrations" % repo_group_name), ] for scope, destination in scopes_destinations: if admin_view: - destination = ADMIN_PREFIX + '/integrations' + destination = ADMIN_PREFIX + "/integrations" form_data = [ - ('csrf_token', csrf_token), - ('__start__', 'options:mapping'), - ('name', 'test integration'), - ('scope', scope), - ('enabled', 'true'), - ('__end__', 'options:mapping'), - ('__start__', 'settings:mapping'), - ('test_int_field', '34'), - ('test_string_field', ''), # empty value on purpose as it's required - ('__end__', 'settings:mapping'), + ("csrf_token", csrf_token), + ("__start__", "options:mapping"), + ("name", "test integration"), + ("scope", scope), + ("enabled", "true"), + ("__end__", "options:mapping"), + ("__start__", "settings:mapping"), + ("test_int_field", "34"), + ("test_string_field", ""), # empty value on purpose as it's required + ("__end__", "settings:mapping"), ] errors_response = app.post(url, form_data) - assert 'Errors exist' in errors_response.text + assert "Errors exist" in errors_response.text - form_data[-2] = ('test_string_field', 'data!') + form_data[-2] = ("test_string_field", "data!") assert Session().query(Integration).count() == 0 created_response = app.post(url, form_data) assert Session().query(Integration).count() == 1 - delete_response = app.post( - created_response.location, - params={'csrf_token': csrf_token, 'delete': 'delete'}) + delete_response = app.post(created_response.location, params={"csrf_token": csrf_token, "delete": "delete"}) assert Session().query(Integration).count() == 0 assert delete_response.location.endswith(destination) - -@pytest.mark.usefixtures('app', 'autologin_user') +@pytest.mark.usefixtures("app", "autologin_user") class TestIntegrationsView(object): pass class TestGlobalIntegrationsView(TestIntegrationsView): def test_index_no_integrations(self): - url = ADMIN_PREFIX + '/integrations' + url = ADMIN_PREFIX + "/integrations" response = self.app.get(url) assert response.status_code == 200 - response.mustcontain('exist yet') + response.mustcontain("exist yet") def test_index_with_integrations(self, global_integration_stub): - url = ADMIN_PREFIX + '/integrations' + url = ADMIN_PREFIX + "/integrations" response = self.app.get(url) assert response.status_code == 200 - response.mustcontain(no=['exist yet']) + response.mustcontain(no=["exist yet"]) response.mustcontain(global_integration_stub.name) - @pytest.mark.parametrize( - 'IntegrationType', integration_type_registry.values()) + @pytest.mark.parametrize("IntegrationType", integration_type_registry.values()) def test_new_integration_page(self, IntegrationType): - url = ADMIN_PREFIX + '/integrations/new' + url = ADMIN_PREFIX + "/integrations/new" response = self.app.get(url, status=200) if not IntegrationType.is_dummy: - url = (ADMIN_PREFIX + '/integrations/{integration}/new').format( - integration=IntegrationType.key) + url = (ADMIN_PREFIX + "/integrations/{integration}/new").format(integration=IntegrationType.key) response.mustcontain(url) - @pytest.mark.parametrize( - 'IntegrationType', integration_type_registry.values()) + @pytest.mark.parametrize("IntegrationType", integration_type_registry.values()) def test_get_create_integration_page(self, IntegrationType): - url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format( - integration_key=IntegrationType.key) + url = ADMIN_PREFIX + "/integrations/{integration_key}/new".format(integration_key=IntegrationType.key) if IntegrationType.is_dummy: self.app.get(url, status=404) else: response = self.app.get(url, status=200) response.mustcontain(IntegrationType.display_name) - def test_post_integration_page(self, StubIntegrationType, csrf_token, - test_repo_group, backend_random): - url = ADMIN_PREFIX + '/integrations/{integration_key}/new'.format( - integration_key=StubIntegrationType.key) + def test_post_integration_page(self, StubIntegrationType, csrf_token, test_repo_group, backend_random): + url = ADMIN_PREFIX + "/integrations/{integration_key}/new".format(integration_key=StubIntegrationType.key) _post_integration_test_helper( - self.app, url, csrf_token, admin_view=True, - repo=backend_random.repo, repo_group=test_repo_group) + self.app, url, csrf_token, admin_view=True, repo=backend_random.repo, repo_group=test_repo_group + ) class TestRepoIntegrationsView(TestIntegrationsView): def test_index_no_integrations(self, backend_random): - url = '/{repo_name}/settings/integrations'.format( - repo_name=backend_random.repo.repo_name) + url = "/{repo_name}/settings/integrations".format(repo_name=backend_random.repo.repo_name) response = self.app.get(url) assert response.status_code == 200 - response.mustcontain('exist yet') + response.mustcontain("exist yet") def test_index_with_integrations(self, repo_integration_stub): - url = '/{repo_name}/settings/integrations'.format( - repo_name=repo_integration_stub.repo.repo_name) + url = "/{repo_name}/settings/integrations".format(repo_name=repo_integration_stub.repo.repo_name) stub_name = repo_integration_stub.name response = self.app.get(url) assert response.status_code == 200 response.mustcontain(stub_name) - response.mustcontain(no=['exist yet']) + response.mustcontain(no=["exist yet"]) - @pytest.mark.parametrize( - 'IntegrationType', integration_type_registry.values()) + @pytest.mark.parametrize("IntegrationType", integration_type_registry.values()) def test_new_integration_page(self, backend_random, IntegrationType): repo_name = backend_random.repo.repo_name - url = '/{repo_name}/settings/integrations/new'.format( - repo_name=repo_name) + url = "/{repo_name}/settings/integrations/new".format(repo_name=repo_name) response = self.app.get(url, status=200) - url = '/{repo_name}/settings/integrations/{integration}/new'.format( - repo_name=repo_name, - integration=IntegrationType.key) + url = "/{repo_name}/settings/integrations/{integration}/new".format( + repo_name=repo_name, integration=IntegrationType.key + ) if not IntegrationType.is_dummy: response.mustcontain(url) - @pytest.mark.parametrize( - 'IntegrationType', integration_type_registry.values()) + @pytest.mark.parametrize("IntegrationType", integration_type_registry.values()) def test_get_create_integration_page(self, backend_random, IntegrationType): repo_name = backend_random.repo.repo_name - url = '/{repo_name}/settings/integrations/{integration_key}/new'.format( - repo_name=repo_name, integration_key=IntegrationType.key) + url = "/{repo_name}/settings/integrations/{integration_key}/new".format( + repo_name=repo_name, integration_key=IntegrationType.key + ) if IntegrationType.is_dummy: self.app.get(url, status=404) else: response = self.app.get(url, status=200) response.mustcontain(IntegrationType.display_name) - def test_post_integration_page(self, backend_random, test_repo_group, - StubIntegrationType, csrf_token): + def test_post_integration_page(self, backend_random, test_repo_group, StubIntegrationType, csrf_token): repo_name = backend_random.repo.repo_name - url = '/{repo_name}/settings/integrations/{integration_key}/new'.format( - repo_name=repo_name, integration_key=StubIntegrationType.key) + url = "/{repo_name}/settings/integrations/{integration_key}/new".format( + repo_name=repo_name, integration_key=StubIntegrationType.key + ) _post_integration_test_helper( - self.app, url, csrf_token, admin_view=False, - repo=backend_random.repo, repo_group=test_repo_group) + self.app, url, csrf_token, admin_view=False, repo=backend_random.repo, repo_group=test_repo_group + ) class TestRepoGroupIntegrationsView(TestIntegrationsView): def test_index_no_integrations(self, test_repo_group): - url = '/{repo_group_name}/_settings/integrations'.format( - repo_group_name=test_repo_group.group_name) + url = "/{repo_group_name}/_settings/integrations".format(repo_group_name=test_repo_group.group_name) response = self.app.get(url) assert response.status_code == 200 - response.mustcontain('exist yet') + response.mustcontain("exist yet") - def test_index_with_integrations( - self, test_repo_group, repogroup_integration_stub): - - url = '/{repo_group_name}/_settings/integrations'.format( - repo_group_name=test_repo_group.group_name) + def test_index_with_integrations(self, test_repo_group, repogroup_integration_stub): + url = "/{repo_group_name}/_settings/integrations".format(repo_group_name=test_repo_group.group_name) stub_name = repogroup_integration_stub.name response = self.app.get(url) assert response.status_code == 200 - response.mustcontain(no=['exist yet']) + response.mustcontain(no=["exist yet"]) response.mustcontain(stub_name) def test_new_integration_page(self, test_repo_group): repo_group_name = test_repo_group.group_name - url = '/{repo_group_name}/_settings/integrations/new'.format( - repo_group_name=test_repo_group.group_name) + url = "/{repo_group_name}/_settings/integrations/new".format(repo_group_name=test_repo_group.group_name) response = self.app.get(url) @@ -228,21 +204,17 @@ class TestRepoGroupIntegrationsView(TestIntegrationsView): for integration_key, integration_obj in integration_type_registry.items(): if not integration_obj.is_dummy: - nurl = ( - '/{repo_group_name}/_settings/integrations/{integration}/new').format( - repo_group_name=repo_group_name, - integration=integration_key) + nurl = ("/{repo_group_name}/_settings/integrations/{integration}/new").format( + repo_group_name=repo_group_name, integration=integration_key + ) response.mustcontain(nurl) - @pytest.mark.parametrize( - 'IntegrationType', integration_type_registry.values()) - def test_get_create_integration_page( - self, test_repo_group, IntegrationType): - + @pytest.mark.parametrize("IntegrationType", integration_type_registry.values()) + def test_get_create_integration_page(self, test_repo_group, IntegrationType): repo_group_name = test_repo_group.group_name - url = ('/{repo_group_name}/_settings/integrations/{integration_key}/new' - ).format(repo_group_name=repo_group_name, - integration_key=IntegrationType.key) + url = ("/{repo_group_name}/_settings/integrations/{integration_key}/new").format( + repo_group_name=repo_group_name, integration_key=IntegrationType.key + ) if not IntegrationType.is_dummy: response = self.app.get(url, status=200) @@ -250,14 +222,12 @@ class TestRepoGroupIntegrationsView(TestIntegrationsView): else: self.app.get(url, status=404) - def test_post_integration_page(self, test_repo_group, backend_random, - StubIntegrationType, csrf_token): - + def test_post_integration_page(self, test_repo_group, backend_random, StubIntegrationType, csrf_token): repo_group_name = test_repo_group.group_name - url = ('/{repo_group_name}/_settings/integrations/{integration_key}/new' - ).format(repo_group_name=repo_group_name, - integration_key=StubIntegrationType.key) + url = ("/{repo_group_name}/_settings/integrations/{integration_key}/new").format( + repo_group_name=repo_group_name, integration_key=StubIntegrationType.key + ) _post_integration_test_helper( - self.app, url, csrf_token, admin_view=False, - repo=backend_random.repo, repo_group=test_repo_group) + self.app, url, csrf_token, admin_view=False, repo=backend_random.repo, repo_group=test_repo_group + ) diff --git a/rhodecode/integrations/types/base.py b/rhodecode/integrations/types/base.py index 1ab2cdb0..b12e9fb8 100644 --- a/rhodecode/integrations/types/base.py +++ b/rhodecode/integrations/types/base.py @@ -38,7 +38,6 @@ log = logging.getLogger(__name__) class UrlTmpl(string.Template): - def safe_substitute(self, **kws): # url encode the kw for usage in url kws = {k: urllib.parse.quote(safe_str(v)) for k, v in kws.items()} @@ -46,13 +45,14 @@ class UrlTmpl(string.Template): class IntegrationTypeBase(object): - """ Base class for IntegrationType plugins """ + """Base class for IntegrationType plugins""" + is_dummy = False - description = '' + description = "" @classmethod def icon(cls): - return ''' + return """ - ''' + """ def __init__(self, settings): """ @@ -132,16 +132,15 @@ class IntegrationTypeBase(object): :param event: :return: bool """ - allowed_events = self.settings.get('events') or [] + allowed_events = self.settings.get("events") or [] if event.name not in allowed_events: - log.debug('event ignored: %r event %s not in allowed set of events %s', - event, event.name, allowed_events) + log.debug("event ignored: %r event %s not in allowed set of events %s", event, event.name, allowed_events) return False return True class EEIntegration(IntegrationTypeBase): - description = 'Integration available in RhodeCode EE edition.' + description = "Integration available in RhodeCode EE edition." is_dummy = True def __init__(self, name, key, settings=None): @@ -154,55 +153,64 @@ class EEIntegration(IntegrationTypeBase): # updating this required to update the `common_vars` as well. WEBHOOK_URL_VARS = [ # GENERAL - ('General', [ - ('event_name', 'Unique name of the event type, e.g pullrequest-update'), - ('repo_name', 'Full name of the repository'), - ('repo_type', 'VCS type of repository'), - ('repo_id', 'Unique id of repository'), - ('repo_url', 'Repository url'), - ] + ( + "General", + [ + ("event_name", "Unique name of the event type, e.g pullrequest-update"), + ("repo_name", "Full name of the repository"), + ("repo_type", "VCS type of repository"), + ("repo_id", "Unique id of repository"), + ("repo_url", "Repository url"), + ], ), # extra repo fields - ('Repository', [ - ('extra:', 'Extra repo variables, read from its settings.'), - ] + ( + "Repository", + [ + ("extra:", "Extra repo variables, read from its settings."), + ], ), # special attrs below that we handle, using multi-call - ('Commit push - Multicalls', [ - ('branch', 'Name of each branch submitted, if any.'), - ('branch_head', 'Head ID of pushed branch (full sha of last commit), if any.'), - ('commit_id', 'ID (full sha) of each commit submitted, if any.'), - ] + ( + "Commit push - Multicalls", + [ + ("branch", "Name of each branch submitted, if any."), + ("branch_head", "Head ID of pushed branch (full sha of last commit), if any."), + ("commit_id", "ID (full sha) of each commit submitted, if any."), + ], ), # pr events vars - ('Pull request', [ - ('pull_request_id', 'Unique ID of the pull request.'), - ('pull_request_title', 'Title of the pull request.'), - ('pull_request_url', 'Pull request url.'), - ('pull_request_shadow_url', 'Pull request shadow repo clone url.'), - ('pull_request_commits_uid', 'Calculated UID of all commits inside the PR. ' - 'Changes after PR update'), - ] + ( + "Pull request", + [ + ("pull_request_id", "Unique ID of the pull request."), + ("pull_request_title", "Title of the pull request."), + ("pull_request_url", "Pull request url."), + ("pull_request_shadow_url", "Pull request shadow repo clone url."), + ("pull_request_commits_uid", "Calculated UID of all commits inside the PR. Changes after PR update"), + ], ), # commit comment event vars - ('Commit comment', [ - ('commit_comment_id', 'Unique ID of the comment made on a commit.'), - ('commit_comment_text', 'Text of commit comment.'), - ('commit_comment_type', 'Type of comment, e.g note/todo.'), - - ('commit_comment_f_path', 'Optionally path of file for inline comments.'), - ('commit_comment_line_no', 'Line number of the file: eg o10, or n200'), - - ('commit_comment_commit_id', 'Commit id that comment was left at.'), - ('commit_comment_commit_branch', 'Commit branch that comment was left at'), - ('commit_comment_commit_message', 'Commit message that comment was left at'), - ] + ( + "Commit comment", + [ + ("commit_comment_id", "Unique ID of the comment made on a commit."), + ("commit_comment_text", "Text of commit comment."), + ("commit_comment_type", "Type of comment, e.g note/todo."), + ("commit_comment_f_path", "Optionally path of file for inline comments."), + ("commit_comment_line_no", "Line number of the file: eg o10, or n200"), + ("commit_comment_commit_id", "Commit id that comment was left at."), + ("commit_comment_commit_branch", "Commit branch that comment was left at"), + ("commit_comment_commit_message", "Commit message that comment was left at"), + ], ), # user who triggers the call - ('Caller', [ - ('username', 'User who triggered the call.'), - ('user_id', 'User id who triggered the call.'), - ] + ( + "Caller", + [ + ("username", "User who triggered the call."), + ("user_id", "User id who triggered the call."), + ], ), ] @@ -211,55 +219,52 @@ CI_URL_VARS = WEBHOOK_URL_VARS class CommitParsingDataHandler(object): - def aggregate_branch_data(self, branches, commits): branch_data = collections.OrderedDict() for obj in branches: - branch_data[obj['name']] = obj + branch_data[obj["name"]] = obj branches_commits = collections.OrderedDict() for commit in commits: - if commit.get('git_ref_change'): + if commit.get("git_ref_change"): # special case for GIT that allows creating tags, # deleting branches without associated commit continue - commit_branch = commit['branch'] + commit_branch = commit["branch"] if commit_branch not in branches_commits: - _branch = branch_data[commit_branch] \ - if commit_branch else commit_branch - branch_commits = {'branch': _branch, - 'branch_head': '', - 'commits': []} + _branch = branch_data[commit_branch] if commit_branch else commit_branch + branch_commits = {"branch": _branch, "branch_head": "", "commits": []} branches_commits[commit_branch] = branch_commits branch_commits = branches_commits[commit_branch] - branch_commits['commits'].append(commit) - branch_commits['branch_head'] = commit['raw_id'] + branch_commits["commits"].append(commit) + branch_commits["branch_head"] = commit["raw_id"] return branches_commits def get_auth(settings): from requests.auth import HTTPBasicAuth - username = settings.get('username') - password = settings.get('password') + + username = settings.get("username") + password = settings.get("password") if username and password: return HTTPBasicAuth(username, password) return None def get_web_token(settings): - return settings['secret_token'] + return settings["secret_token"] def get_url_vars(url_vars): items = [] for section, section_items in url_vars: - items.append(f'\n*{section}*') + items.append(f"\n*{section}*") for key, explanation in section_items: - items.append(' {} - {}'.format('${' + key + '}', explanation)) - return '\n'.join(items) + items.append(" {} - {}".format("${" + key + "}", explanation)) + return "\n".join(items) def render_with_traceback(template, *args, **kwargs): @@ -274,9 +279,7 @@ STATUS_400 = (400, 401, 403) STATUS_500 = (500, 502, 504) -def requests_retry_call( - retries=3, backoff_factor=0.3, status_forcelist=STATUS_400+STATUS_500, - session=None): +def requests_retry_call(retries=3, backoff_factor=0.3, status_forcelist=STATUS_400 + STATUS_500, session=None): """ session = requests_retry_session() response = session.get('http://example.com') @@ -295,6 +298,6 @@ def requests_retry_call( status_forcelist=status_forcelist, ) adapter = HTTPAdapter(max_retries=retry) - session.mount('http://', adapter) - session.mount('https://', adapter) + session.mount("http://", adapter) + session.mount("https://", adapter) return session diff --git a/rhodecode/integrations/types/email.py b/rhodecode/integrations/types/email.py index 2da2acbc..591ca3a5 100644 --- a/rhodecode/integrations/types/email.py +++ b/rhodecode/integrations/types/email.py @@ -28,13 +28,12 @@ from rhodecode.model.validation_schema.widgets import CheckboxChoiceWidgetDesc from rhodecode.translation import _ from rhodecode.lib.celerylib import run_task from rhodecode.lib.celerylib import tasks -from rhodecode.integrations.types.base import ( - IntegrationTypeBase, render_with_traceback) +from rhodecode.integrations.types.base import IntegrationTypeBase, render_with_traceback log = logging.getLogger(__name__) -REPO_PUSH_TEMPLATE_PLAINTEXT = Template(''' +REPO_PUSH_TEMPLATE_PLAINTEXT = Template(""" Commits: % for commit in data['push']['commits']: @@ -43,9 +42,9 @@ ${commit['message']} ---- % endfor -''') +""") -REPO_PUSH_TEMPLATE_HTML = Template(''' +REPO_PUSH_TEMPLATE_HTML = Template(""" @@ -146,40 +145,38 @@ REPO_PUSH_TEMPLATE_HTML = Template('''

-''') +""") class EmailSettingsSchema(colander.Schema): @colander.instantiate(validator=colander.Length(min=1)) class recipients(colander.SequenceSchema): - title = _('Recipients') - description = _('Email addresses to send push events to') + title = _("Recipients") + description = _("Email addresses to send push events to") widget = deform.widget.SequenceWidget(min_len=1) recipient = colander.SchemaNode( colander.String(), - title=_('Email address'), - description=_('Email address'), - default='', + title=_("Email address"), + description=_("Email address"), + default="", validator=colander.Email(), widget=deform.widget.TextInputWidget( - placeholder='user@domain.com', + placeholder="user@domain.com", ), ) class EmailIntegrationType(IntegrationTypeBase): - key = 'email' - display_name = _('Email') - description = _('Send repo push summaries to a list of recipients via email') + key = "email" + display_name = _("Email") + description = _("Send repo push summaries to a list of recipients via email") - valid_events = [ - events.RepoPushEvent - ] + valid_events = [events.RepoPushEvent] @classmethod def icon(cls): - return ''' + return """ -''' +""" def settings_schema(self): schema = EmailSettingsSchema() - schema.add(colander.SchemaNode( - colander.Set(), - widget=CheckboxChoiceWidgetDesc( - values=sorted( - [(e.name, e.display_name, e.description) for e in self.valid_events] + schema.add( + colander.SchemaNode( + colander.Set(), + widget=CheckboxChoiceWidgetDesc( + values=sorted([(e.name, e.display_name, e.description) for e in self.valid_events]), ), - ), - description="List of events activated for this integration", - name='events' - )) + description="List of events activated for this integration", + name="events", + ) + ) return schema def send_event(self, event): - log.debug('handling event %s with integration %s', event.name, self) + log.debug("handling event %s with integration %s", event.name, self) if event.__class__ not in self.valid_events: - log.debug('event %r not present in valid event list (%s)', event, self.valid_events) + log.debug("event %r not present in valid event list (%s)", event, self.valid_events) return if not self.event_enabled(event): @@ -279,49 +276,43 @@ class EmailEventHandler(object): if isinstance(event, events.RepoPushEvent): self.repo_push_handler(event, event_data) else: - log.debug('ignoring event: %r', event) + log.debug("ignoring event: %r", event) def repo_push_handler(self, event, data): - commit_num = len(data['push']['commits']) - server_url = data['server_url'] + commit_num = len(data["push"]["commits"]) + server_url = data["server_url"] if commit_num == 1: - if data['push']['branches']: - _subject = '[{repo_name}] {author} pushed {commit_num} commit on branches: {branches}' + if data["push"]["branches"]: + _subject = "[{repo_name}] {author} pushed {commit_num} commit on branches: {branches}" else: - _subject = '[{repo_name}] {author} pushed {commit_num} commit' + _subject = "[{repo_name}] {author} pushed {commit_num} commit" subject = _subject.format( - author=data['actor']['username'], - repo_name=data['repo']['repo_name'], + author=data["actor"]["username"], + repo_name=data["repo"]["repo_name"], commit_num=commit_num, - branches=', '.join( - branch['name'] for branch in data['push']['branches']) + branches=", ".join(branch["name"] for branch in data["push"]["branches"]), ) else: - if data['push']['branches']: - _subject = '[{repo_name}] {author} pushed {commit_num} commits on branches: {branches}' + if data["push"]["branches"]: + _subject = "[{repo_name}] {author} pushed {commit_num} commits on branches: {branches}" else: - _subject = '[{repo_name}] {author} pushed {commit_num} commits' + _subject = "[{repo_name}] {author} pushed {commit_num} commits" subject = _subject.format( - author=data['actor']['username'], - repo_name=data['repo']['repo_name'], + author=data["actor"]["username"], + repo_name=data["repo"]["repo_name"], commit_num=commit_num, - branches=', '.join( - branch['name'] for branch in data['push']['branches'])) + branches=", ".join(branch["name"] for branch in data["push"]["branches"]), + ) email_body_plaintext = render_with_traceback( - REPO_PUSH_TEMPLATE_PLAINTEXT, - data=data, - subject=subject, - instance_url=server_url) + REPO_PUSH_TEMPLATE_PLAINTEXT, data=data, subject=subject, instance_url=server_url + ) email_body_html = render_with_traceback( - REPO_PUSH_TEMPLATE_HTML, - data=data, - subject=subject, - instance_url=server_url) + REPO_PUSH_TEMPLATE_HTML, data=data, subject=subject, instance_url=server_url + ) - recipients = self.integration_settings['recipients'] + recipients = self.integration_settings["recipients"] for email_address in recipients: - run_task(tasks.send_email, email_address, subject, - email_body_plaintext, email_body_html) + run_task(tasks.send_email, email_address, subject, email_body_plaintext, email_body_html) diff --git a/rhodecode/integrations/types/handlers/slack.py b/rhodecode/integrations/types/handlers/slack.py index aaed64b6..2ca104b8 100644 --- a/rhodecode/integrations/types/handlers/slack.py +++ b/rhodecode/integrations/types/handlers/slack.py @@ -37,10 +37,10 @@ class SlackData: def html_to_slack_links(message): - return re.compile(r'(.+?)').sub(r'<\1|\2>', message) + return re.compile(r'(.+?)').sub(r"<\1|\2>", message) -REPO_PUSH_TEMPLATE = Template(''' +REPO_PUSH_TEMPLATE = Template(""" <% def branch_text(branch): if branch: @@ -56,11 +56,11 @@ ${len(branch_commits['commits'])} ${'commit' if len(branch_commits['commits']) = `<${commit['url']}|${commit['short_id']}>` - ${commit['message_html']|html_to_slack_links} % endfor % endfor -''') +""") class SlackDataHandler(CommitParsingDataHandler): - name = 'slack' + name = "slack" def __init__(self): pass @@ -70,19 +70,15 @@ class SlackDataHandler(CommitParsingDataHandler): raise TypeError(f"event {event} is not subtype of events.RhodecodeEvent") actor = data["actor"]["username"] - default_title = f'*{actor}* caused a *{event.name}* event' - default_text = f'*{actor}* caused a *{event.name}* event' + default_title = f"*{actor}* caused a *{event.name}* event" + default_text = f"*{actor}* caused a *{event.name}* event" default_slack_data = SlackData(title=default_title, text=default_text) if isinstance(event, events.PullRequestCommentEvent): - return self.format_pull_request_comment_event( - event, data, default_slack_data - ) + return self.format_pull_request_comment_event(event, data, default_slack_data) elif isinstance(event, events.PullRequestCommentEditEvent): - return self.format_pull_request_comment_event( - event, data, default_slack_data - ) + return self.format_pull_request_comment_event(event, data, default_slack_data) elif isinstance(event, events.PullRequestReviewEvent): return self.format_pull_request_review_event(event, data, default_slack_data) elif isinstance(event, events.PullRequestEvent): @@ -92,61 +88,53 @@ class SlackDataHandler(CommitParsingDataHandler): elif isinstance(event, events.RepoCreateEvent): return self.format_repo_create_event(event, data, default_slack_data) else: - raise ValueError( - f'event type `{event.__class__}` has no handler defined') + raise ValueError(f"event type `{event.__class__}` has no handler defined") def format_pull_request_comment_event(self, event, data, slack_data): - comment_text = data['comment']['text'] + comment_text = data["comment"]["text"] if len(comment_text) > 200: - comment_text = '<{comment_url}|{comment_text}...>'.format( + comment_text = "<{comment_url}|{comment_text}...>".format( comment_text=comment_text[:200], - comment_url=data['comment']['url'], + comment_url=data["comment"]["url"], ) fields = None overrides = None status_text = None - if data['comment']['status']: - status_color = { - 'approved': '#0ac878', - 'rejected': '#e85e4d'}.get(data['comment']['status']) + if data["comment"]["status"]: + status_color = {"approved": "#0ac878", "rejected": "#e85e4d"}.get(data["comment"]["status"]) if status_color: overrides = {"color": status_color} - status_text = data['comment']['status'] + status_text = data["comment"]["status"] - if data['comment']['file']: + if data["comment"]["file"]: fields = [ - { - "title": "file", - "value": data['comment']['file'] - }, - { - "title": "line", - "value": data['comment']['line'] - } + {"title": "file", "value": data["comment"]["file"]}, + {"title": "line", "value": data["comment"]["line"]}, ] - template = Template(textwrap.dedent(r''' + template = Template( + textwrap.dedent(r""" *${data['actor']['username']}* left ${data['comment']['type']} on pull request <${data['pullrequest']['url']}|#${data['pullrequest']['pull_request_id']}>: - ''')) - title = render_with_traceback( - template, data=data, comment=event.comment) + """) + ) + title = render_with_traceback(template, data=data, comment=event.comment) - template = Template(textwrap.dedent(r''' + template = Template( + textwrap.dedent(r""" *pull request title*: ${pr_title} % if status_text: *submitted status*: `${status_text}` % endif >>> ${comment_text} - ''')) + """) + ) text = render_with_traceback( - template, - comment_text=comment_text, - pr_title=data['pullrequest']['title'], - status_text=status_text) + template, comment_text=comment_text, pr_title=data["pullrequest"]["title"], status_text=status_text + ) slack_data.title = title slack_data.text = text @@ -156,17 +144,19 @@ class SlackDataHandler(CommitParsingDataHandler): return slack_data def format_pull_request_review_event(self, event, data, slack_data) -> SlackData: - template = Template(textwrap.dedent(r''' + template = Template( + textwrap.dedent(r""" *${data['actor']['username']}* changed status of pull request <${data['pullrequest']['url']}|#${data['pullrequest']['pull_request_id']} to `${data['pullrequest']['status']}`>: - ''')) + """) + ) title = render_with_traceback(template, data=data) - template = Template(textwrap.dedent(r''' + template = Template( + textwrap.dedent(r""" *pull request title*: ${pr_title} - ''')) - text = render_with_traceback( - template, - pr_title=data['pullrequest']['title']) + """) + ) + text = render_with_traceback(template, pr_title=data["pullrequest"]["title"]) slack_data.title = title slack_data.text = text @@ -175,27 +165,28 @@ class SlackDataHandler(CommitParsingDataHandler): def format_pull_request_event(self, event, data, slack_data) -> SlackData: action = { - events.PullRequestCloseEvent: 'closed', - events.PullRequestMergeEvent: 'merged', - events.PullRequestUpdateEvent: 'updated', - events.PullRequestCreateEvent: 'created', + events.PullRequestCloseEvent: "closed", + events.PullRequestMergeEvent: "merged", + events.PullRequestUpdateEvent: "updated", + events.PullRequestCreateEvent: "created", }.get(event.__class__, str(event.__class__)) - template = Template(textwrap.dedent(r''' + template = Template( + textwrap.dedent(r""" *${data['actor']['username']}* `${action}` pull request <${data['pullrequest']['url']}|#${data['pullrequest']['pull_request_id']}>: - ''')) + """) + ) title = render_with_traceback(template, data=data, action=action) - template = Template(textwrap.dedent(r''' + template = Template( + textwrap.dedent(r""" *pull request title*: ${pr_title} %if data['pullrequest']['commits']: *commits*: ${len(data['pullrequest']['commits'])} %endif - ''')) - text = render_with_traceback( - template, - pr_title=data['pullrequest']['title'], - data=data) + """) + ) + text = render_with_traceback(template, pr_title=data["pullrequest"]["title"], data=data) slack_data.title = title slack_data.text = text @@ -203,12 +194,11 @@ class SlackDataHandler(CommitParsingDataHandler): return slack_data def format_repo_push_event(self, event, data, slack_data) -> SlackData: - branches_commits = self.aggregate_branch_data( - data['push']['branches'], data['push']['commits']) + branches_commits = self.aggregate_branch_data(data["push"]["branches"], data["push"]["commits"]) - template = Template(r''' + template = Template(r""" *${data['actor']['username']}* pushed to repo <${data['repo']['url']}|${data['repo']['repo_name']}>: - ''') + """) title = render_with_traceback(template, data=data) text = render_with_traceback( @@ -224,18 +214,20 @@ class SlackDataHandler(CommitParsingDataHandler): return slack_data def format_repo_create_event(self, event, data, slack_data) -> SlackData: - template = Template(r''' + template = Template(r""" *${data['actor']['username']}* created new repository ${data['repo']['repo_name']}: - ''') + """) title = render_with_traceback(template, data=data) - template = Template(textwrap.dedent(r''' + template = Template( + textwrap.dedent(r""" repo_url: ${data['repo']['url']} repo_type: ${data['repo']['repo_type']} - ''')) + """) + ) text = render_with_traceback(template, data=data) slack_data.title = title slack_data.text = text - return slack_data \ No newline at end of file + return slack_data diff --git a/rhodecode/integrations/types/handlers/webhook.py b/rhodecode/integrations/types/handlers/webhook.py index 4447b8b2..745ce161 100644 --- a/rhodecode/integrations/types/handlers/webhook.py +++ b/rhodecode/integrations/types/handlers/webhook.py @@ -26,7 +26,7 @@ log = logging.getLogger(__name__) class WebhookDataHandler(CommitParsingDataHandler): - name = 'webhook' + name = "webhook" def __init__(self, template_url, headers): self.template_url = template_url @@ -39,21 +39,21 @@ class WebhookDataHandler(CommitParsingDataHandler): """ # note: make sure to update the `WEBHOOK_URL_VARS` if this changes common_vars = { - 'repo_name': data['repo']['repo_name'], - 'repo_type': data['repo']['repo_type'], - 'repo_id': data['repo']['repo_id'], - 'repo_url': data['repo']['url'], - 'username': data['actor']['username'], - 'user_id': data['actor']['user_id'], - 'event_name': data['name'] + "repo_name": data["repo"]["repo_name"], + "repo_type": data["repo"]["repo_type"], + "repo_id": data["repo"]["repo_id"], + "repo_url": data["repo"]["url"], + "username": data["actor"]["username"], + "user_id": data["actor"]["user_id"], + "event_name": data["name"], } extra_vars = {} - for extra_key, extra_val in data['repo']['extra_fields'].items(): - extra_vars[f'extra__{extra_key}'] = extra_val + for extra_key, extra_val in data["repo"]["extra_fields"].items(): + extra_vars[f"extra__{extra_key}"] = extra_val common_vars.update(extra_vars) - template_url = self.template_url.replace('${extra:', '${extra__') + template_url = self.template_url.replace("${extra:", "${extra__") for k, v in common_vars.items(): template_url = UrlTmpl(template_url).safe_substitute(**{k: v}) return template_url @@ -62,56 +62,49 @@ class WebhookDataHandler(CommitParsingDataHandler): url = self.get_base_parsed_template(data) url_calls = [] - branches_commits = self.aggregate_branch_data( - data['push']['branches'], data['push']['commits']) - if '${branch}' in url or '${branch_head}' in url or '${commit_id}' in url: + branches_commits = self.aggregate_branch_data(data["push"]["branches"], data["push"]["commits"]) + if "${branch}" in url or "${branch_head}" in url or "${commit_id}" in url: # call it multiple times, for each branch if used in variables for branch, commit_ids in branches_commits.items(): branch_url = UrlTmpl(url).safe_substitute(branch=branch) - if '${branch_head}' in branch_url: + if "${branch_head}" in branch_url: # last commit in the aggregate is the head of the branch - branch_head = commit_ids['branch_head'] + branch_head = commit_ids["branch_head"] branch_url = UrlTmpl(branch_url).safe_substitute(branch_head=branch_head) # call further down for each commit if used - if '${commit_id}' in branch_url: - for commit_data in commit_ids['commits']: - commit_id = commit_data['raw_id'] + if "${commit_id}" in branch_url: + for commit_data in commit_ids["commits"]: + commit_id = commit_data["raw_id"] commit_url = UrlTmpl(branch_url).safe_substitute(commit_id=commit_id) # register per-commit call - log.debug( - 'register %s call(%s) to url %s', - self.name, event, commit_url) - url_calls.append( - (commit_url, self.headers, data)) + log.debug("register %s call(%s) to url %s", self.name, event, commit_url) + url_calls.append((commit_url, self.headers, data)) else: # register per-branch call - log.debug('register %s call(%s) to url %s', - self.name, event, branch_url) + log.debug("register %s call(%s) to url %s", self.name, event, branch_url) url_calls.append((branch_url, self.headers, data)) else: - log.debug('register %s call(%s) to url %s', self.name, event, url) + log.debug("register %s call(%s) to url %s", self.name, event, url) url_calls.append((url, self.headers, data)) return url_calls def repo_commit_comment_handler(self, event, data): url = self.get_base_parsed_template(data) - log.debug('register %s call(%s) to url %s', self.name, event, url) + log.debug("register %s call(%s) to url %s", self.name, event, url) comment_vars = [ - ('commit_comment_id', data['comment']['comment_id']), - ('commit_comment_text', data['comment']['comment_text']), - ('commit_comment_type', data['comment']['comment_type']), - - ('commit_comment_f_path', data['comment']['comment_f_path']), - ('commit_comment_line_no', data['comment']['comment_line_no']), - - ('commit_comment_commit_id', data['commit']['commit_id']), - ('commit_comment_commit_branch', data['commit']['commit_branch']), - ('commit_comment_commit_message', data['commit']['commit_message']), + ("commit_comment_id", data["comment"]["comment_id"]), + ("commit_comment_text", data["comment"]["comment_text"]), + ("commit_comment_type", data["comment"]["comment_type"]), + ("commit_comment_f_path", data["comment"]["comment_f_path"]), + ("commit_comment_line_no", data["comment"]["comment_line_no"]), + ("commit_comment_commit_id", data["commit"]["commit_id"]), + ("commit_comment_commit_branch", data["commit"]["commit_branch"]), + ("commit_comment_commit_message", data["commit"]["commit_message"]), ] for k, v in comment_vars: url = UrlTmpl(url).safe_substitute(**{k: v}) @@ -120,18 +113,16 @@ class WebhookDataHandler(CommitParsingDataHandler): def repo_commit_comment_edit_handler(self, event, data): url = self.get_base_parsed_template(data) - log.debug('register %s call(%s) to url %s', self.name, event, url) + log.debug("register %s call(%s) to url %s", self.name, event, url) comment_vars = [ - ('commit_comment_id', data['comment']['comment_id']), - ('commit_comment_text', data['comment']['comment_text']), - ('commit_comment_type', data['comment']['comment_type']), - - ('commit_comment_f_path', data['comment']['comment_f_path']), - ('commit_comment_line_no', data['comment']['comment_line_no']), - - ('commit_comment_commit_id', data['commit']['commit_id']), - ('commit_comment_commit_branch', data['commit']['commit_branch']), - ('commit_comment_commit_message', data['commit']['commit_message']), + ("commit_comment_id", data["comment"]["comment_id"]), + ("commit_comment_text", data["comment"]["comment_text"]), + ("commit_comment_type", data["comment"]["comment_type"]), + ("commit_comment_f_path", data["comment"]["comment_f_path"]), + ("commit_comment_line_no", data["comment"]["comment_line_no"]), + ("commit_comment_commit_id", data["commit"]["commit_id"]), + ("commit_comment_commit_branch", data["commit"]["commit_branch"]), + ("commit_comment_commit_message", data["commit"]["commit_message"]), ] for k, v in comment_vars: url = UrlTmpl(url).safe_substitute(**{k: v}) @@ -140,18 +131,18 @@ class WebhookDataHandler(CommitParsingDataHandler): def repo_create_event_handler(self, event, data): url = self.get_base_parsed_template(data) - log.debug('register %s call(%s) to url %s', self.name, event, url) + log.debug("register %s call(%s) to url %s", self.name, event, url) return [(url, self.headers, data)] def pull_request_event_handler(self, event, data): url = self.get_base_parsed_template(data) - log.debug('register %s call(%s) to url %s', self.name, event, url) + log.debug("register %s call(%s) to url %s", self.name, event, url) pr_vars = [ - ('pull_request_id', data['pullrequest']['pull_request_id']), - ('pull_request_title', data['pullrequest']['title']), - ('pull_request_url', data['pullrequest']['url']), - ('pull_request_shadow_url', data['pullrequest']['shadow_url']), - ('pull_request_commits_uid', data['pullrequest']['commits_uid']), + ("pull_request_id", data["pullrequest"]["pull_request_id"]), + ("pull_request_title", data["pullrequest"]["title"]), + ("pull_request_url", data["pullrequest"]["url"]), + ("pull_request_shadow_url", data["pullrequest"]["shadow_url"]), + ("pull_request_commits_uid", data["pullrequest"]["commits_uid"]), ] for k, v in pr_vars: url = UrlTmpl(url).safe_substitute(**{k: v}) @@ -159,7 +150,6 @@ class WebhookDataHandler(CommitParsingDataHandler): return [(url, self.headers, data)] def __call__(self, event, data): - if isinstance(event, events.RepoPushEvent): return self.repo_push_event_handler(event, data) elif isinstance(event, events.RepoCreateEvent): @@ -171,5 +161,4 @@ class WebhookDataHandler(CommitParsingDataHandler): elif isinstance(event, events.PullRequestEvent): return self.pull_request_event_handler(event, data) else: - raise ValueError( - f'event type `{event.__class__}` has no handler defined') + raise ValueError(f"event type `{event.__class__}` has no handler defined") diff --git a/rhodecode/integrations/types/slack.py b/rhodecode/integrations/types/slack.py index 3ad30bb8..75e769d8 100644 --- a/rhodecode/integrations/types/slack.py +++ b/rhodecode/integrations/types/slack.py @@ -17,11 +17,10 @@ # and proprietary license terms, please see https://rhodecode.com/licenses/ - import time import logging -import deform # noqa +import deform # noqa import deform.widget import colander @@ -45,59 +44,55 @@ log = logging.getLogger(__name__) class SlackSettingsSchema(colander.Schema): service = colander.SchemaNode( colander.String(), - title=_('Slack service URL'), - description=h.literal(_( - 'This can be setup at the ' - '' - 'slack app manager')), - default='', + title=_("Slack service URL"), + description=h.literal( + _( + "This can be setup at the " + '' + "slack app manager" + ) + ), + default="", preparer=strip_whitespace, validator=colander.url, widget=deform.widget.TextInputWidget( - placeholder='https://hooks.slack.com/services/...', + placeholder="https://hooks.slack.com/services/...", ), ) username = colander.SchemaNode( colander.String(), - title=_('Username'), - description=_('Username to show notifications coming from.'), - missing='Rhodecode', + title=_("Username"), + description=_("Username to show notifications coming from."), + missing="Rhodecode", preparer=strip_whitespace, - widget=deform.widget.TextInputWidget( - placeholder='Rhodecode' - ), + widget=deform.widget.TextInputWidget(placeholder="Rhodecode"), ) channel = colander.SchemaNode( colander.String(), - title=_('Channel'), - description=_('Channel to send notifications to.'), - missing='', + title=_("Channel"), + description=_("Channel to send notifications to."), + missing="", preparer=strip_whitespace, - widget=deform.widget.TextInputWidget( - placeholder='#general' - ), + widget=deform.widget.TextInputWidget(placeholder="#general"), ) icon_emoji = colander.SchemaNode( colander.String(), - title=_('Emoji'), - description=_('Emoji to use eg. :studio_microphone:'), - missing='', + title=_("Emoji"), + description=_("Emoji to use eg. :studio_microphone:"), + missing="", preparer=strip_whitespace, - widget=deform.widget.TextInputWidget( - placeholder=':studio_microphone:' - ), + widget=deform.widget.TextInputWidget(placeholder=":studio_microphone:"), ) class SlackIntegrationType(IntegrationTypeBase): - key = 'slack' - display_name = _('Slack') - description = _('Send events such as repo pushes and pull requests to ' - 'your slack channel.') + key = "slack" + display_name = _("Slack") + description = _("Send events such as repo pushes and pull requests to your slack channel.") @classmethod def icon(cls): - return '''''' + return """""" valid_events = [ events.PullRequestCloseEvent, @@ -112,24 +107,24 @@ class SlackIntegrationType(IntegrationTypeBase): def settings_schema(self): schema = SlackSettingsSchema() - schema.add(colander.SchemaNode( - colander.Set(), - widget=CheckboxChoiceWidgetDesc( - values=sorted( - [(e.name, e.display_name, e.description) for e in self.valid_events] + schema.add( + colander.SchemaNode( + colander.Set(), + widget=CheckboxChoiceWidgetDesc( + values=sorted([(e.name, e.display_name, e.description) for e in self.valid_events]), ), - ), - description="List of events activated for this integration", - name='events' - )) + description="List of events activated for this integration", + name="events", + ) + ) return schema def send_event(self, event): - log.debug('handling event %s with integration %s', event.name, self) + log.debug("handling event %s with integration %s", event.name, self) if event.__class__ not in self.valid_events: - log.debug('event %r not present in valid event list (%s)', event, self.valid_events) + log.debug("event %r not present in valid event list (%s)", event, self.valid_events) return if not self.event_enabled(event): @@ -154,36 +149,36 @@ def post_text_to_slack(settings, slack_data: SlackData): fields = slack_data.fields overrides = slack_data.overrides - log.debug('sending %s (%s) to slack %s', title, text, settings['service']) + log.debug("sending %s (%s) to slack %s", title, text, settings["service"]) fields = fields or [] overrides = overrides or {} message_data = { - "fallback": text, - "color": "#427cc9", - "pretext": title, - #"author_name": "Bobby Tables", - #"author_link": "http://flickr.com/bobby/", - #"author_icon": "http://flickr.com/icons/bobby.jpg", - #"title": "Slack API Documentation", - #"title_link": "https://api.slack.com/", - "text": text, - "fields": fields, - #"image_url": "http://my-website.com/path/to/image.jpg", - #"thumb_url": "http://example.com/path/to/thumb.png", - "footer": "RhodeCode", - #"footer_icon": "", - "ts": time.time(), - "mrkdwn_in": ["pretext", "text"] + "fallback": text, + "color": "#427cc9", + "pretext": title, + # "author_name": "Bobby Tables", + # "author_link": "http://flickr.com/bobby/", + # "author_icon": "http://flickr.com/icons/bobby.jpg", + # "title": "Slack API Documentation", + # "title_link": "https://api.slack.com/", + "text": text, + "fields": fields, + # "image_url": "http://my-website.com/path/to/image.jpg", + # "thumb_url": "http://example.com/path/to/thumb.png", + "footer": "RhodeCode", + # "footer_icon": "", + "ts": time.time(), + "mrkdwn_in": ["pretext", "text"], } message_data.update(overrides) json_message = { - "icon_emoji": settings.get('icon_emoji', ':studio_microphone:'), - "channel": settings.get('channel', ''), - "username": settings.get('username', 'Rhodecode'), - "attachments": [message_data] + "icon_emoji": settings.get("icon_emoji", ":studio_microphone:"), + "channel": settings.get("channel", ""), + "username": settings.get("username", "Rhodecode"), + "attachments": [message_data], } req_session = requests_retry_call() - resp = req_session.post(settings['service'], json=json_message, timeout=60) + resp = req_session.post(settings["service"], json=json_message, timeout=60) resp.raise_for_status() # raise exception on a failed request diff --git a/rhodecode/integrations/types/webhook.py b/rhodecode/integrations/types/webhook.py index f1838382..95b0829d 100644 --- a/rhodecode/integrations/types/webhook.py +++ b/rhodecode/integrations/types/webhook.py @@ -17,7 +17,7 @@ # and proprietary license terms, please see https://rhodecode.com/licenses/ -import deform # noqa +import deform # noqa import deform.widget import logging import colander @@ -50,98 +50,91 @@ URL_VARS = get_url_vars(WEBHOOK_URL_VARS) class WebhookSettingsSchema(colander.Schema): url = colander.SchemaNode( colander.String(), - title=_('Webhook URL'), - description= - _('URL to which Webhook should submit data. If used some of the ' - 'variables would trigger multiple calls, like ${branch} or ' - '${commit_id}. Webhook will be called as many times as unique ' - 'objects in data in such cases.'), + title=_("Webhook URL"), + description=_( + "URL to which Webhook should submit data. If used some of the " + "variables would trigger multiple calls, like ${branch} or " + "${commit_id}. Webhook will be called as many times as unique " + "objects in data in such cases." + ), missing=colander.required, required=True, preparer=strip_whitespace, validator=colander.url, widget=widgets.CodeMirrorWidget( - help_block_collapsable_name='Show url variables', + help_block_collapsable_name="Show url variables", help_block_collapsable=( - 'E.g https://my-serv.com/trigger_job/${{event_name}}' - '?PR_ID=${{pull_request_id}}' - '\nFull list of vars:\n{}'.format(URL_VARS)), - codemirror_mode='text', - codemirror_options='{"lineNumbers": false, "lineWrapping": true}'), + "E.g https://my-serv.com/trigger_job/${{event_name}}" + "?PR_ID=${{pull_request_id}}" + "\nFull list of vars:\n{}".format(URL_VARS) + ), + codemirror_mode="text", + codemirror_options='{"lineNumbers": false, "lineWrapping": true}', + ), ) secret_token = colander.SchemaNode( colander.String(), - title=_('Secret Token'), - description=_('Optional string used to validate received payloads. ' - 'It will be sent together with event data in JSON'), - default='', - missing='', - widget=deform.widget.TextInputWidget( - placeholder='e.g. secret_token' + title=_("Secret Token"), + description=_( + "Optional string used to validate received payloads. It will be sent together with event data in JSON" ), + default="", + missing="", + widget=deform.widget.TextInputWidget(placeholder="e.g. secret_token"), ) username = colander.SchemaNode( colander.String(), - title=_('Username'), - description=_('Optional username to authenticate the call.'), - default='', - missing='', - widget=deform.widget.TextInputWidget( - placeholder='e.g. admin' - ), + title=_("Username"), + description=_("Optional username to authenticate the call."), + default="", + missing="", + widget=deform.widget.TextInputWidget(placeholder="e.g. admin"), ) password = colander.SchemaNode( colander.String(), - title=_('Password'), - description=_('Optional password to authenticate the call.'), - default='', - missing='', + title=_("Password"), + description=_("Optional password to authenticate the call."), + default="", + missing="", widget=deform.widget.PasswordWidget( - placeholder='e.g. secret.', + placeholder="e.g. secret.", redisplay=True, ), ) custom_header_key = colander.SchemaNode( colander.String(), - title=_('Custom Header Key'), - description=_('Custom Header name to be set when calling endpoint.'), - default='', - missing='', - widget=deform.widget.TextInputWidget( - placeholder='e.g: Authorization' - ), + title=_("Custom Header Key"), + description=_("Custom Header name to be set when calling endpoint."), + default="", + missing="", + widget=deform.widget.TextInputWidget(placeholder="e.g: Authorization"), ) custom_header_val = colander.SchemaNode( colander.String(), - title=_('Custom Header Value'), - description=_('Custom Header value to be set when calling endpoint.'), - default='', - missing='', - widget=deform.widget.TextInputWidget( - placeholder='e.g. Basic XxXxXx' - ), + title=_("Custom Header Value"), + description=_("Custom Header value to be set when calling endpoint."), + default="", + missing="", + widget=deform.widget.TextInputWidget(placeholder="e.g. Basic XxXxXx"), ) method_type = colander.SchemaNode( colander.String(), - title=_('Call Method'), - description=_('Select a HTTP method to use when calling the Webhook.'), - default='post', - missing='', - widget=deform.widget.RadioChoiceWidget( - values=[('get', 'GET'), ('post', 'POST'), ('put', 'PUT')], - inline=True - ), + title=_("Call Method"), + description=_("Select a HTTP method to use when calling the Webhook."), + default="post", + missing="", + widget=deform.widget.RadioChoiceWidget(values=[("get", "GET"), ("post", "POST"), ("put", "PUT")], inline=True), ) class WebhookIntegrationType(IntegrationTypeBase): - key = 'webhook' - display_name = _('Webhook') - description = _('send JSON data to a url endpoint') + key = "webhook" + display_name = _("Webhook") + description = _("send JSON data to a url endpoint") @classmethod def icon(cls): - return '''''' + return """""" valid_events = [ events.PullRequestCloseEvent, @@ -159,41 +152,41 @@ class WebhookIntegrationType(IntegrationTypeBase): def settings_schema(self): schema = WebhookSettingsSchema() - schema.add(colander.SchemaNode( - colander.Set(), - widget=CheckboxChoiceWidgetDesc( - values=sorted( - [(e.name, e.display_name, e.description) for e in self.valid_events] + schema.add( + colander.SchemaNode( + colander.Set(), + widget=CheckboxChoiceWidgetDesc( + values=sorted([(e.name, e.display_name, e.description) for e in self.valid_events]), ), - ), - description="List of events activated for this integration", - name='events' - )) + description="List of events activated for this integration", + name="events", + ) + ) return schema def send_event(self, event): - log.debug('handling event %s with integration %s', event.name, self) + log.debug("handling event %s with integration %s", event.name, self) if event.__class__ not in self.valid_events: - log.debug('event %r not present in valid event list (%s)', event, self.valid_events) + log.debug("event %r not present in valid event list (%s)", event, self.valid_events) return if not self.event_enabled(event): return data = event.as_dict() - template_url = self.settings['url'] + template_url = self.settings["url"] headers = {} - head_key = self.settings.get('custom_header_key') - head_val = self.settings.get('custom_header_val') + head_key = self.settings.get("custom_header_key") + head_val = self.settings.get("custom_header_val") if head_key and head_val: headers = {head_key: head_val} handler = WebhookDataHandler(template_url, headers) url_calls = handler(event, data) - log.debug('Webhook: calling following urls: %s', [x[0] for x in url_calls]) + log.debug("Webhook: calling following urls: %s", [x[0] for x in url_calls]) run_task(post_to_webhook, self.settings, url_calls) @@ -239,7 +232,7 @@ def post_to_webhook(settings, url_calls): """ call_headers = { - 'User-Agent': f'RhodeCode-webhook-caller/{rhodecode.__version__}' + "User-Agent": f"RhodeCode-webhook-caller/{rhodecode.__version__}" } # updated below with custom ones, allows override auth = get_auth(settings) @@ -248,20 +241,17 @@ def post_to_webhook(settings, url_calls): for url, headers, data in url_calls: req_session = requests_retry_call() - method = settings.get('method_type') or 'post' + method = settings.get("method_type") or "post" call_method = getattr(req_session, method) headers = headers or {} call_headers.update(headers) - log.debug('calling Webhook with method: %s, and auth:%s', call_method, auth) - if settings.get('log_data'): - log.debug('calling webhook with data: %s', data) - resp = call_method(url, json={ - 'token': token, - 'event': data - }, headers=call_headers, auth=auth, timeout=60) - log.debug('Got Webhook response: %s', resp) + log.debug("calling Webhook with method: %s, and auth:%s", call_method, auth) + if settings.get("log_data"): + log.debug("calling webhook with data: %s", data) + resp = call_method(url, json={"token": token, "event": data}, headers=call_headers, auth=auth, timeout=60) + log.debug("Got Webhook response: %s", resp) try: resp.raise_for_status() # raise exception on a failed request diff --git a/rhodecode/integrations/views.py b/rhodecode/integrations/views.py index 038ab7a5..246d6f1f 100644 --- a/rhodecode/integrations/views.py +++ b/rhodecode/integrations/views.py @@ -26,16 +26,19 @@ from rhodecode.integrations import integration_type_registry from rhodecode.apps._base import BaseAppView from rhodecode.apps._base.navigation import navigation_list from rhodecode.lib.auth import ( - LoginRequired, CSRFRequired, HasPermissionAnyDecorator, - HasRepoPermissionAnyDecorator, HasRepoGroupPermissionAnyDecorator) + LoginRequired, + CSRFRequired, + HasPermissionAnyDecorator, + HasRepoPermissionAnyDecorator, + HasRepoGroupPermissionAnyDecorator, +) from rhodecode.lib.utils2 import safe_int from rhodecode.lib.helpers import Page from rhodecode.lib import helpers as h from rhodecode.model.db import Repository, RepoGroup, Session, Integration from rhodecode.model.scm import ScmModel from rhodecode.model.integration import IntegrationModel -from rhodecode.model.validation_schema.schemas.integration_schema import ( - make_integration_schema, IntegrationScopeType) +from rhodecode.model.validation_schema.schemas.integration_schema import make_integration_schema, IntegrationScopeType log = logging.getLogger(__name__) @@ -64,16 +67,16 @@ class IntegrationSettingsViewBase(BaseAppView): request = self.request - if 'repo_name' in request.matchdict: # in repo settings context - repo_name = request.matchdict['repo_name'] + if "repo_name" in request.matchdict: # in repo settings context + repo_name = request.matchdict["repo_name"] self.repo = Repository.get_by_repo_name(repo_name) - if 'repo_group_name' in request.matchdict: # in group settings context - repo_group_name = request.matchdict['repo_group_name'] + if "repo_group_name" in request.matchdict: # in group settings context + repo_group_name = request.matchdict["repo_group_name"] self.repo_group = RepoGroup.get_by_group_name(repo_group_name) - if 'integration' in request.matchdict: # integration type context - integration_type = request.matchdict['integration'] + if "integration" in request.matchdict: # integration type context + integration_type = request.matchdict["integration"] if integration_type not in integration_type_registry: raise HTTPNotFound() @@ -81,8 +84,8 @@ class IntegrationSettingsViewBase(BaseAppView): if self.IntegrationType.is_dummy: raise HTTPNotFound() - if 'integration_id' in request.matchdict: # single integration context - integration_id = request.matchdict['integration_id'] + if "integration_id" in request.matchdict: # single integration context + integration_id = request.matchdict["integration_id"] self.integration = Integration.get(integration_id) # extra perms check just in case @@ -95,69 +98,60 @@ class IntegrationSettingsViewBase(BaseAppView): def _has_perms_for_integration(self, integration): perms = self.request.user.permissions - if 'hg.admin' in perms['global']: + if "hg.admin" in perms["global"]: return True if integration.repo: - return perms['repositories'].get( - integration.repo.repo_name) == 'repository.admin' + return perms["repositories"].get(integration.repo.repo_name) == "repository.admin" if integration.repo_group: - return perms['repositories_groups'].get( - integration.repo_group.group_name) == 'group.admin' + return perms["repositories_groups"].get(integration.repo_group.group_name) == "group.admin" return False def _get_local_tmpl_context(self, include_app_defaults=True): _ = self.request.translate - c = super()._get_local_tmpl_context( - include_app_defaults=include_app_defaults) - c.active = 'integrations' + c = super()._get_local_tmpl_context(include_app_defaults=include_app_defaults) + c.active = "integrations" return c def _form_schema(self): - schema = make_integration_schema(IntegrationType=self.IntegrationType, - settings=self.settings) + schema = make_integration_schema(IntegrationType=self.IntegrationType, settings=self.settings) # returns a clone, important if mutating the schema later - return schema.bind( - permissions=self.request.user.permissions, - no_scope=not self.admin_view) + return schema.bind(permissions=self.request.user.permissions, no_scope=not self.admin_view) def _form_defaults(self): _ = self.request.translate defaults = {} if self.integration: - defaults['settings'] = self.integration.settings or {} - defaults['options'] = { - 'name': self.integration.name, - 'enabled': self.integration.enabled, - 'scope': { - 'repo': self.integration.repo, - 'repo_group': self.integration.repo_group, - 'child_repos_only': self.integration.child_repos_only, + defaults["settings"] = self.integration.settings or {} + defaults["options"] = { + "name": self.integration.name, + "enabled": self.integration.enabled, + "scope": { + "repo": self.integration.repo, + "repo_group": self.integration.repo_group, + "child_repos_only": self.integration.child_repos_only, }, } else: if self.repo: - scope = _('{repo_name} repository').format( - repo_name=self.repo.repo_name) + scope = _("{repo_name} repository").format(repo_name=self.repo.repo_name) elif self.repo_group: - scope = _('{repo_group_name} repo group').format( - repo_group_name=self.repo_group.group_name) + scope = _("{repo_group_name} repo group").format(repo_group_name=self.repo_group.group_name) else: - scope = _('Global') + scope = _("Global") - defaults['options'] = { - 'enabled': True, - 'name': _('{name} integration').format( - name=self.IntegrationType.display_name), + defaults["options"] = { + "enabled": True, + "name": _("{name} integration").format(name=self.IntegrationType.display_name), } - defaults['options']['scope'] = { - 'repo': self.repo, - 'repo_group': self.repo_group, + defaults["options"]["scope"] = { + "repo": self.repo, + "repo_group": self.repo_group, } return defaults @@ -167,23 +161,22 @@ class IntegrationSettingsViewBase(BaseAppView): Session().delete(integration) Session().commit() h.flash( - _('Integration {integration_name} deleted successfully.').format( - integration_name=integration.name), - category='success') + _("Integration {integration_name} deleted successfully.").format(integration_name=integration.name), + category="success", + ) if self.repo: - redirect_to = self.request.route_path( - 'repo_integrations_home', repo_name=self.repo.repo_name) + redirect_to = self.request.route_path("repo_integrations_home", repo_name=self.repo.repo_name) elif self.repo_group: redirect_to = self.request.route_path( - 'repo_group_integrations_home', - repo_group_name=self.repo_group.group_name) + "repo_group_integrations_home", repo_group_name=self.repo_group.group_name + ) else: - redirect_to = self.request.route_path('global_integrations_home') + redirect_to = self.request.route_path("global_integrations_home") raise HTTPFound(redirect_to) def _integration_list(self): - """ List integrations """ + """List integrations""" c = self.load_default_context() if self.repo: @@ -191,44 +184,39 @@ class IntegrationSettingsViewBase(BaseAppView): elif self.repo_group: scope = self.repo_group else: - scope = 'all' + scope = "all" integrations = [] for IntType, integration in IntegrationModel().get_integrations( - scope=scope, IntegrationType=self.IntegrationType): - + scope=scope, IntegrationType=self.IntegrationType + ): # extra permissions check *just in case* if not self._has_perms_for_integration(integration): continue integrations.append((IntType, integration)) - sort_arg = self.request.GET.get('sort', 'name:asc') - sort_dir = 'asc' - if ':' in sort_arg: - sort_field, sort_dir = sort_arg.split(':') + sort_arg = self.request.GET.get("sort", "name:asc") + sort_dir = "asc" + if ":" in sort_arg: + sort_field, sort_dir = sort_arg.split(":") else: - sort_field = sort_arg, 'asc' + sort_field = sort_arg, "asc" - assert sort_field in ('name', 'integration_type', 'enabled', 'scope') + assert sort_field in ("name", "integration_type", "enabled", "scope") - integrations.sort( - key=lambda x: getattr(x[1], sort_field), - reverse=(sort_dir == 'desc')) + integrations.sort(key=lambda x: getattr(x[1], sort_field), reverse=(sort_dir == "desc")) def url_generator(page_num): - query_params = { - 'page': page_num - } + query_params = {"page": page_num} return self.request.current_route_path(_query=query_params) - page = safe_int(self.request.GET.get('page', 1), 1) + page = safe_int(self.request.GET.get("page", 1), 1) - integrations = Page( - integrations, page=page, items_per_page=10, url_maker=url_generator) + integrations = Page(integrations, page=page, items_per_page=10, url_maker=url_generator) - c.rev_sort_dir = sort_dir != 'desc' and 'desc' or 'asc' + c.rev_sort_dir = sort_dir != "desc" and "desc" or "asc" c.current_IntegrationType = self.IntegrationType c.integrations_list = integrations @@ -246,9 +234,9 @@ class IntegrationSettingsViewBase(BaseAppView): schema = self._form_schema() if self.integration: - buttons = ('submit', 'delete') + buttons = ("submit", "delete") else: - buttons = ('submit',) + buttons = ("submit",) form = form or deform.Form(schema, appstruct=defaults, buttons=buttons) @@ -267,42 +255,42 @@ class IntegrationSettingsViewBase(BaseAppView): controls = list(self.request.POST.items()) pstruct = peppercorn.parse(controls) - if self.integration and pstruct.get('delete'): + if self.integration and pstruct.get("delete"): return self._delete_integration(self.integration) schema = self._form_schema() skip_settings_validation = False - if self.integration and 'enabled' not in pstruct.get('options', {}): + if self.integration and "enabled" not in pstruct.get("options", {}): skip_settings_validation = True - schema['settings'].validator = None - for field in schema['settings'].children: + schema["settings"].validator = None + for field in schema["settings"].children: field.validator = None - field.missing = '' + field.missing = "" if self.integration: - buttons = ('submit', 'delete') + buttons = ("submit", "delete") else: - buttons = ('submit',) + buttons = ("submit",) form = deform.Form(schema, buttons=buttons) if not self.admin_view: # scope is read only field in these cases, and has to be added - options = pstruct.setdefault('options', {}) - if 'scope' not in options: - options['scope'] = IntegrationScopeType().serialize(None, { - 'repo': self.repo, - 'repo_group': self.repo_group, - }) + options = pstruct.setdefault("options", {}) + if "scope" not in options: + options["scope"] = IntegrationScopeType().serialize( + None, + { + "repo": self.repo, + "repo_group": self.repo_group, + }, + ) try: valid_data = form.validate_pstruct(pstruct) except deform.ValidationFailure as e: - h.flash( - _('Errors exist when saving integration settings. ' - 'Please check the form inputs.'), - category='error') + h.flash(_("Errors exist when saving integration settings. Please check the form inputs."), category="error") return self._settings_get(form=e) if not self.integration: @@ -310,24 +298,27 @@ class IntegrationSettingsViewBase(BaseAppView): self.integration.integration_type = self.IntegrationType.key Session().add(self.integration) - scope = valid_data['options']['scope'] + scope = valid_data["options"]["scope"] - IntegrationModel().update_integration(self.integration, - name=valid_data['options']['name'], - enabled=valid_data['options']['enabled'], - settings=valid_data['settings'], - repo=scope['repo'], - repo_group=scope['repo_group'], - child_repos_only=scope['child_repos_only'], + IntegrationModel().update_integration( + self.integration, + name=valid_data["options"]["name"], + enabled=valid_data["options"]["enabled"], + settings=valid_data["settings"], + repo=scope["repo"], + repo_group=scope["repo_group"], + child_repos_only=scope["child_repos_only"], ) - self.integration.settings = valid_data['settings'] + self.integration.settings = valid_data["settings"] Session().commit() # Display success message and redirect. h.flash( - _('Integration {integration_name} updated successfully.').format( - integration_name=self.IntegrationType.display_name), - category='success') + _("Integration {integration_name} updated successfully.").format( + integration_name=self.IntegrationType.display_name + ), + category="success", + ) # if integration scope changes, we must redirect to the right place # keeping in mind if the original view was for /repo/ or /_admin/ @@ -335,21 +326,24 @@ class IntegrationSettingsViewBase(BaseAppView): if self.integration.repo and not admin_view: redirect_to = self.request.route_path( - 'repo_integrations_edit', + "repo_integrations_edit", repo_name=self.integration.repo.repo_name, integration=self.integration.integration_type, - integration_id=self.integration.integration_id) + integration_id=self.integration.integration_id, + ) elif self.integration.repo_group and not admin_view: redirect_to = self.request.route_path( - 'repo_group_integrations_edit', + "repo_group_integrations_edit", repo_group_name=self.integration.repo_group.group_name, integration=self.integration.integration_type, - integration_id=self.integration.integration_id) + integration_id=self.integration.integration_id, + ) else: redirect_to = self.request.route_path( - 'global_integrations_edit', + "global_integrations_edit", integration=self.integration.integration_type, - integration_id=self.integration.integration_id) + integration_id=self.integration.integration_id, + ) return HTTPFound(redirect_to) @@ -372,23 +366,23 @@ class GlobalIntegrationsView(IntegrationSettingsViewBase): return c @LoginRequired() - @HasPermissionAnyDecorator('hg.admin') + @HasPermissionAnyDecorator("hg.admin") def integration_list(self): return self._integration_list() @LoginRequired() - @HasPermissionAnyDecorator('hg.admin') + @HasPermissionAnyDecorator("hg.admin") def settings_get(self): return self._settings_get() @LoginRequired() - @HasPermissionAnyDecorator('hg.admin') + @HasPermissionAnyDecorator("hg.admin") @CSRFRequired() def settings_post(self): return self._settings_post() @LoginRequired() - @HasPermissionAnyDecorator('hg.admin') + @HasPermissionAnyDecorator("hg.admin") def new_integration(self): return self._new_integration() @@ -405,33 +399,32 @@ class RepoIntegrationsView(IntegrationSettingsViewBase): c.repo_name = self.db_repo.repo_name c.repository_pull_requests = ScmModel().get_pull_requests(self.repo) c.repository_artifacts = ScmModel().get_artifacts(self.repo) - c.repository_is_user_following = ScmModel().is_following_repo( - c.repo_name, self._rhodecode_user.user_id) + c.repository_is_user_following = ScmModel().is_following_repo(c.repo_name, self._rhodecode_user.user_id) c.has_origin_repo_read_perm = False if self.db_repo.fork: c.has_origin_repo_read_perm = h.HasRepoPermissionAny( - 'repository.write', 'repository.read', 'repository.admin')( - self.db_repo.fork.repo_name, 'summary fork link') + "repository.write", "repository.read", "repository.admin" + )(self.db_repo.fork.repo_name, "summary fork link") return c @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def integration_list(self): return self._integration_list() @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def settings_get(self): return self._settings_get() @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") @CSRFRequired() def settings_post(self): return self._settings_post() @LoginRequired() - @HasRepoPermissionAnyDecorator('repository.admin') + @HasRepoPermissionAnyDecorator("repository.admin") def new_integration(self): return self._new_integration() @@ -446,22 +439,22 @@ class RepoGroupIntegrationsView(IntegrationSettingsViewBase): return c @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") def integration_list(self): return self._integration_list() @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") def settings_get(self): return self._settings_get() @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") @CSRFRequired() def settings_post(self): return self._settings_post() @LoginRequired() - @HasRepoGroupPermissionAnyDecorator('group.admin') + @HasRepoGroupPermissionAnyDecorator("group.admin") def new_integration(self): return self._new_integration() diff --git a/rhodecode/lib/_vendor/authomatic/adapters.py b/rhodecode/lib/_vendor/authomatic/adapters.py index 361fe769..154bd712 100755 --- a/rhodecode/lib/_vendor/authomatic/adapters.py +++ b/rhodecode/lib/_vendor/authomatic/adapters.py @@ -1,4 +1,3 @@ - """ Adapters -------- @@ -171,7 +170,7 @@ class DjangoAdapter(BaseAdapter): self.response[key] = value def set_status(self, status): - status_code, reason = status.split(' ', 1) + status_code, reason = status.split(" ", 1) self.response.status_code = int(status_code) @@ -271,7 +270,7 @@ class WerkzeugAdapter(BaseAdapter): self.response = response def write(self, value): - self.response.data = self.response.data.decode('utf-8') + value + self.response.data = self.response.data.decode("utf-8") + value def set_header(self, key, value): self.response.headers[key] = value diff --git a/rhodecode/lib/_vendor/authomatic/core.py b/rhodecode/lib/_vendor/authomatic/core.py index 173fdf1c..ec585c7f 100755 --- a/rhodecode/lib/_vendor/authomatic/core.py +++ b/rhodecode/lib/_vendor/authomatic/core.py @@ -1,5 +1,3 @@ - - import collections import copy import datetime @@ -7,6 +5,7 @@ import hashlib import hmac import json import logging + try: import cPickle as pickle except ImportError: @@ -50,8 +49,7 @@ def normalize_dict(dict_): """ - return dict([(k, v[0] if not isinstance(v, str) and len(v) == 1 else v) - for k, v in list(dict_.items())]) + return dict([(k, v[0] if not isinstance(v, str) and len(v) == 1 else v) for k, v in list(dict_.items())]) def items_to_dict(items): @@ -137,7 +135,7 @@ def escape(s): """ Escape a URL including any /. """ - return parse.quote(s.encode('utf-8'), safe='~') + return parse.quote(s.encode("utf-8"), safe="~") def json_qs_parser(body): @@ -178,15 +176,14 @@ def import_string(import_name, silent=False): """ try: - if '.' in import_name: - module, obj = import_name.rsplit('.', 1) + if "." in import_name: + module, obj = import_name.rsplit(".", 1) return getattr(__import__(module, None, None, [obj]), obj) else: return __import__(import_name) except (ImportError, AttributeError) as e: if not silent: - raise ImportStringError('Import from string failed for path {0}' - .format(import_name), str(e)) + raise ImportStringError("Import from string failed for path {0}".format(import_name), str(e)) def resolve_provider_class(class_): @@ -200,7 +197,7 @@ def resolve_provider_class(class_): if isinstance(class_, str): # prepare path for authomatic.providers package - path = '.'.join([__package__, 'providers', class_]) + path = ".".join([__package__, "providers", class_]) # try to import class by string from providers module or by fully # qualified path @@ -221,11 +218,10 @@ def id_to_name(config, short_name): """ for k, v in list(config.items()): - if v.get('id') == short_name: + if v.get("id") == short_name: return k - raise Exception( - 'No provider with id={0} found in the config!'.format(short_name)) + raise Exception("No provider with id={0} found in the config!".format(short_name)) class ReprMixin(object): @@ -252,7 +248,6 @@ class ReprMixin(object): _repr_length_limit = 20 def __repr__(self): - # get class name name = self.__class__.__name__ @@ -260,25 +255,23 @@ class ReprMixin(object): args = [] for k, v in list(self.__dict__.items()): - # ignore attributes with leading underscores and those listed in # _repr_ignore - if v and not k.startswith('_') and k not in self._repr_ignore: - + if v and not k.startswith("_") and k not in self._repr_ignore: # replace sensitive values if k in self._repr_sensitive: - v = '###' + v = "###" # if repr is too long if len(repr(v)) > self._repr_length_limit: # Truncate to ClassName(...) - v = '{0}(...)'.format(v.__class__.__name__) + v = "{0}(...)".format(v.__class__.__name__) else: v = repr(v) - args.append('{0}={1}'.format(k, v)) + args.append("{0}={1}".format(k, v)) - return '{0}({1})'.format(name, ', '.join(args)) + return "{0}({1})".format(name, ", ".join(args)) class Future(threading.Thread): @@ -340,8 +333,7 @@ class Session(object): A dictionary-like secure cookie session implementation. """ - def __init__(self, adapter, secret, name='authomatic', max_age=600, - secure=False): + def __init__(self, adapter, secret, name="authomatic", max_age=600, secure=False): """ :param str secret: Session secret used to sign the session cookie. @@ -370,25 +362,24 @@ class Session(object): Expires value will be ``Thu, 01-Jan-1970 00:00:01 GMT``. """ - value = 'deleted' if delete else self._serialize(self.data) + value = "deleted" if delete else self._serialize(self.data) split_url = parse.urlsplit(self.adapter.url) - domain = split_url.netloc.split(':')[0] + domain = split_url.netloc.split(":")[0] # Work-around for issue #11, failure of WebKit-based browsers to accept # cookies set as part of a redirect response in some circumstances. - if '.' not in domain: - template = '{name}={value}; Path={path}; HttpOnly{secure}{expires}' + if "." not in domain: + template = "{name}={value}; Path={path}; HttpOnly{secure}{expires}" else: - template = ('{name}={value}; Domain={domain}; Path={path}; ' - 'HttpOnly{secure}{expires}') + template = "{name}={value}; Domain={domain}; Path={path}; HttpOnly{secure}{expires}" return template.format( name=self.name, value=value, domain=domain, path=split_url.path, - secure='; Secure' if self.secure else '', - expires='; Expires=Thu, 01-Jan-1970 00:00:01 GMT' if delete else '' + secure="; Secure" if self.secure else "", + expires="; Expires=Thu, 01-Jan-1970 00:00:01 GMT" if delete else "", ) def save(self): @@ -400,17 +391,15 @@ class Session(object): cookie_len = len(cookie) if cookie_len > 4093: - raise SessionError('Cookie too long! The cookie size {0} ' - 'is more than 4093 bytes.' - .format(cookie_len)) + raise SessionError("Cookie too long! The cookie size {0} is more than 4093 bytes.".format(cookie_len)) - self.adapter.set_header('Set-Cookie', cookie) + self.adapter.set_header("Set-Cookie", cookie) # Reset data self._data = {} def delete(self): - self.adapter.set_header('Set-Cookie', self.create_cookie(delete=True)) + self.adapter.set_header("Set-Cookie", self.create_cookie(delete=True)) def _get_data(self): """ @@ -436,7 +425,7 @@ class Session(object): Creates signature for the session. """ signature = hmac.new(six.b(self.secret), digestmod=hashlib.sha1) - signature.update(six.b('|'.join(parts))) + signature.update(six.b("|".join(parts))) return signature.hexdigest() def _serialize(self, value): @@ -455,16 +444,16 @@ class Session(object): data = value # 1. Serialize - serialized = pickle.dumps(data).decode('latin-1') + serialized = pickle.dumps(data).decode("latin-1") # 2. Encode # Percent encoding produces smaller result then urlsafe base64. - encoded = parse.quote(serialized, '') + encoded = parse.quote(serialized, "") # 3. Concatenate timestamp = str(int(time.time())) signature = self._signature(self.name, encoded, timestamp) - concatenated = '|'.join([encoded, timestamp, signature]) + concatenated = "|".join([encoded, timestamp, signature]) return concatenated @@ -481,7 +470,7 @@ class Session(object): """ # 3. Split - encoded, timestamp, signature = value.split('|') + encoded, timestamp, signature = value.split("|") # Verify signature if not signature == self._signature(self.name, encoded, timestamp): @@ -495,7 +484,7 @@ class Session(object): decoded = parse.unquote(encoded) # 1. Deserialize - deserialized = pickle.loads(decoded.encode('latin-1')) + deserialized = pickle.loads(decoded.encode("latin-1")) return deserialized @@ -526,58 +515,58 @@ class User(ReprMixin): self.provider = provider #: An :class:`.Credentials` instance. - self.credentials = kwargs.get('credentials') + self.credentials = kwargs.get("credentials") #: A :class:`dict` containing all the **user** information returned #: by the **provider**. #: The structure differs across **providers**. - self.data = kwargs.get('data') + self.data = kwargs.get("data") #: The :attr:`.Response.content` of the request made to update #: the user. - self.content = kwargs.get('content') + self.content = kwargs.get("content") #: :class:`str` ID assigned to the **user** by the **provider**. - self.id = kwargs.get('id') + self.id = kwargs.get("id") #: :class:`str` User name e.g. *andrewpipkin*. - self.username = kwargs.get('username') + self.username = kwargs.get("username") #: :class:`str` Name e.g. *Andrew Pipkin*. - self.name = kwargs.get('name') + self.name = kwargs.get("name") #: :class:`str` First name e.g. *Andrew*. - self.first_name = kwargs.get('first_name') + self.first_name = kwargs.get("first_name") #: :class:`str` Last name e.g. *Pipkin*. - self.last_name = kwargs.get('last_name') + self.last_name = kwargs.get("last_name") #: :class:`str` Nickname e.g. *Andy*. - self.nickname = kwargs.get('nickname') + self.nickname = kwargs.get("nickname") #: :class:`str` Link URL. - self.link = kwargs.get('link') + self.link = kwargs.get("link") #: :class:`str` Gender. - self.gender = kwargs.get('gender') + self.gender = kwargs.get("gender") #: :class:`str` Timezone. - self.timezone = kwargs.get('timezone') + self.timezone = kwargs.get("timezone") #: :class:`str` Locale. - self.locale = kwargs.get('locale') + self.locale = kwargs.get("locale") #: :class:`str` E-mail. - self.email = kwargs.get('email') + self.email = kwargs.get("email") #: :class:`str` phone. - self.phone = kwargs.get('phone') + self.phone = kwargs.get("phone") #: :class:`str` Picture URL. - self.picture = kwargs.get('picture') + self.picture = kwargs.get("picture") #: Birth date as :class:`datetime.datetime()` or :class:`str` # if parsing failed or ``None``. - self.birth_date = kwargs.get('birth_date') + self.birth_date = kwargs.get("birth_date") #: :class:`str` Country. - self.country = kwargs.get('country') + self.country = kwargs.get("country") #: :class:`str` City. - self.city = kwargs.get('city') + self.city = kwargs.get("city") #: :class:`str` Geographical location. - self.location = kwargs.get('location') + self.location = kwargs.get("location") #: :class:`str` Postal code. - self.postal_code = kwargs.get('postal_code') + self.postal_code = kwargs.get("postal_code") #: Instance of the Google App Engine Users API #: `User `_ class. #: Only present when using the :class:`authomatic.providers.gaeopenid.GAEOpenID` provider. - self.gae_user = kwargs.get('gae_user') + self.gae_user = kwargs.get("gae_user") def update(self): """ @@ -618,26 +607,41 @@ class User(ReprMixin): d = copy.copy(self.__dict__) # Keep only the provider name to avoid circular reference - d['provider'] = self.provider.name - d['credentials'] = self.credentials.serialize( - ) if self.credentials else None - d['birth_date'] = str(d['birth_date']) + d["provider"] = self.provider.name + d["credentials"] = self.credentials.serialize() if self.credentials else None + d["birth_date"] = str(d["birth_date"]) # Remove content - d.pop('content') + d.pop("content") if isinstance(self.data, ElementTree.Element): - d['data'] = None + d["data"] = None return d SupportedUserAttributesNT = collections.namedtuple( - typename='SupportedUserAttributesNT', - field_names=['birth_date', 'city', 'country', 'email', 'first_name', - 'gender', 'id', 'last_name', 'link', 'locale', 'location', - 'name', 'nickname', 'phone', 'picture', 'postal_code', - 'timezone', 'username', ] + typename="SupportedUserAttributesNT", + field_names=[ + "birth_date", + "city", + "country", + "email", + "first_name", + "gender", + "id", + "last_name", + "link", + "locale", + "location", + "name", + "nickname", + "phone", + "picture", + "postal_code", + "timezone", + "username", + ], ) @@ -653,33 +657,31 @@ class Credentials(ReprMixin): Contains all necessary information to fetch **user's protected resources**. """ - _repr_sensitive = ('token', 'refresh_token', 'token_secret', - 'consumer_key', 'consumer_secret') + _repr_sensitive = ("token", "refresh_token", "token_secret", "consumer_key", "consumer_secret") def __init__(self, config, **kwargs): - #: :class:`dict` :doc:`config`. self.config = config #: :class:`str` User **access token**. - self.token = kwargs.get('token', '') + self.token = kwargs.get("token", "") #: :class:`str` Access token type. - self.token_type = kwargs.get('token_type', '') + self.token_type = kwargs.get("token_type", "") #: :class:`str` Refresh token. - self.refresh_token = kwargs.get('refresh_token', '') + self.refresh_token = kwargs.get("refresh_token", "") #: :class:`str` Access token secret. - self.token_secret = kwargs.get('token_secret', '') + self.token_secret = kwargs.get("token_secret", "") #: :class:`int` Expiration date as UNIX timestamp. - self.expiration_time = int(kwargs.get('expiration_time', 0)) + self.expiration_time = int(kwargs.get("expiration_time", 0)) #: A :doc:`Provider ` instance**. - provider = kwargs.get('provider') + provider = kwargs.get("provider") - self.expire_in = int(kwargs.get('expire_in', 0)) + self.expire_in = int(kwargs.get("expire_in", 0)) if provider: #: :class:`str` Provider name specified in the :doc:`config`. @@ -706,20 +708,18 @@ class Credentials(ReprMixin): self.consumer_secret = provider.consumer_secret else: - self.provider_name = kwargs.get('provider_name', '') - self.provider_type = kwargs.get('provider_type', '') - self.provider_type_id = kwargs.get('provider_type_id') - self.provider_id = kwargs.get('provider_id') - self.provider_class = kwargs.get('provider_class') + self.provider_name = kwargs.get("provider_name", "") + self.provider_type = kwargs.get("provider_type", "") + self.provider_type_id = kwargs.get("provider_type_id") + self.provider_id = kwargs.get("provider_id") + self.provider_class = kwargs.get("provider_class") - self.consumer_key = kwargs.get('consumer_key', '') - self.consumer_secret = kwargs.get('consumer_secret', '') + self.consumer_key = kwargs.get("consumer_key", "") + self.consumer_secret = kwargs.get("consumer_secret", "") @property def expire_in(self): - """ - - """ + """ """ return self._expire_in @@ -740,7 +740,6 @@ class Credentials(ReprMixin): @expiration_time.setter def expiration_time(self, value): - # pylint:disable=attribute-defined-outside-init self._expiration_time = int(value) self._expire_in = self._expiration_time - int(time.time()) @@ -811,11 +810,10 @@ class Credentials(ReprMixin): """ - if hasattr(self.provider_class, 'refresh_credentials'): + if hasattr(self.provider_class, "refresh_credentials"): if force or self.expire_soon(soon): - logging.info('PROVIDER NAME: {0}'.format(self.provider_name)) - return self.provider_class( - self, None, self.provider_name).refresh_credentials(self) + logging.info("PROVIDER NAME: {0}".format(self.provider_name)) + return self.provider_class(self, None, self.provider_name).refresh_credentials(self) def async_refresh(self, *args, **kwargs): """ @@ -856,9 +854,10 @@ class Credentials(ReprMixin): if self.provider_id is None: raise ConfigError( - 'To serialize credentials you need to specify a ' + "To serialize credentials you need to specify a " 'unique integer under the "id" key in the config ' - 'for each provider!') + "for each provider!" + ) # Get the provider type specific items. rest = self.provider_type_class().to_tuple(self) @@ -870,10 +869,10 @@ class Credentials(ReprMixin): stringified = [str(i) for i in result] # Concatenate by newline. - concatenated = '\n'.join(stringified) + concatenated = "\n".join(stringified) # Percent encode. - return parse.quote(concatenated, '') + return parse.quote(concatenated, "") @classmethod def deserialize(cls, config, credentials): @@ -900,20 +899,21 @@ class Credentials(ReprMixin): decoded = parse.unquote(credentials) - split = decoded.split('\n') + split = decoded.split("\n") # We need the provider ID to move forward. if split[0] is None: raise CredentialsError( - 'To deserialize credentials you need to specify a unique ' - 'integer under the "id" key in the config for each provider!') + "To deserialize credentials you need to specify a unique " + 'integer under the "id" key in the config for each provider!' + ) # Get provider config by short name. provider_name = id_to_name(config, int(split[0])) cfg = config.get(provider_name) # Get the provider class. - ProviderClass = resolve_provider_class(cfg.get('class_')) + ProviderClass = resolve_provider_class(cfg.get("class_")) deserialized = Credentials(config) @@ -940,8 +940,7 @@ class LoginResult(ReprMixin): #: An instance of the :exc:`authomatic.exceptions.BaseError` subclass. self.error = None - def popup_js(self, callback_name=None, indent=None, - custom=None, stay_open=False): + def popup_js(self, callback_name=None, indent=None, custom=None, stay_open=False): """ Returns JavaScript that: @@ -975,9 +974,13 @@ class LoginResult(ReprMixin): """ - custom_callback = """ + custom_callback = ( + """ try {{ window.opener.{cb}(result, closer); }} catch(e) {{}} - """.format(cb=callback_name) if callback_name else '' + """.format(cb=callback_name) + if callback_name + else "" + ) # TODO: Move the window.close() to the opener return """ @@ -998,13 +1001,14 @@ class LoginResult(ReprMixin): }})(); - """.format(result=self.to_json(indent), - custom=json.dumps(custom), - custom_callback=custom_callback, - stay_open='// ' if stay_open else '') + """.format( + result=self.to_json(indent), + custom=json.dumps(custom), + custom_callback=custom_callback, + stay_open="// " if stay_open else "", + ) - def popup_html(self, callback_name=None, indent=None, - title='Login | {0}', custom=None, stay_open=False): + def popup_html(self, callback_name=None, indent=None, title="Login | {0}", custom=None, stay_open=False): """ Returns a HTML with JavaScript that: @@ -1053,8 +1057,8 @@ class LoginResult(ReprMixin): """.format( - title=title.format(self.provider.name if self.provider else ''), - js=self.popup_js(callback_name, indent, custom, stay_open) + title=title.format(self.provider.name if self.provider else ""), + js=self.popup_js(callback_name, indent, custom, stay_open), ) @property @@ -1069,8 +1073,7 @@ class LoginResult(ReprMixin): return dict(provider=self.provider, user=self.user, error=self.error) def to_json(self, indent=4): - return json.dumps(self, default=lambda obj: obj.to_dict( - ) if hasattr(obj, 'to_dict') else '', indent=indent) + return json.dumps(self, default=lambda obj: obj.to_dict() if hasattr(obj, "to_dict") else "", indent=indent) class Response(ReprMixin): @@ -1144,8 +1147,7 @@ class Response(ReprMixin): Return true if string is binary data. """ - textchars = (bytearray([7, 8, 9, 10, 12, 13, 27]) - + bytearray(range(0x20, 0x100))) + textchars = bytearray([7, 8, 9, 10, 12, 13, 27]) + bytearray(range(0x20, 0x100)) return bool(content.translate(None, textchars)) @property @@ -1159,7 +1161,7 @@ class Response(ReprMixin): if self.is_binary_string(content): self._content = content else: - self._content = content.decode('utf-8') + self._content = content.decode("utf-8") return self._content @property @@ -1251,22 +1253,28 @@ class RequestElements(tuple): URL with query string. """ - return self.url + '?' + self.query_string + return self.url + "?" + self.query_string def to_json(self): - return json.dumps(dict(url=self.url, - method=self.method, - params=self.params, - headers=self.headers, - body=self.body)) + return json.dumps( + dict(url=self.url, method=self.method, params=self.params, headers=self.headers, body=self.body) + ) class Authomatic(object): def __init__( - self, config, secret, session_max_age=600, secure_cookie=False, - session=None, session_save_method=None, report_errors=True, - debug=False, logging_level=logging.INFO, prefix='authomatic', - logger=None + self, + config, + secret, + session_max_age=600, + secure_cookie=False, + session=None, + session_save_method=None, + report_errors=True, + debug=False, + logging_level=logging.INFO, + prefix="authomatic", + logger=None, ): """ Encapsulates all the functionality of this package. @@ -1333,8 +1341,7 @@ class Authomatic(object): if logger is None: self._logger.setLevel(logging_level) - def login(self, adapter, provider_name, callback=None, - session=None, session_saver=None, **kwargs): + def login(self, adapter, provider_name, callback=None, session=None, session_saver=None, **kwargs): """ If :data:`provider_name` specified, launches the login procedure for corresponding :doc:`provider ` and returns @@ -1373,40 +1380,43 @@ class Authomatic(object): # exceptions if missing provider_settings = self.config.get(provider_name) if not provider_settings: - raise ConfigError('Provider name "{0}" not specified!' - .format(provider_name)) + raise ConfigError('Provider name "{0}" not specified!'.format(provider_name)) if not (session is None or session_saver is None): session = session session_saver = session_saver else: - session = Session(adapter=adapter, - secret=self.secret, - max_age=self.session_max_age, - name=self.prefix, - secure=self.secure_cookie) + session = Session( + adapter=adapter, + secret=self.secret, + max_age=self.session_max_age, + name=self.prefix, + secure=self.secure_cookie, + ) session_saver = session.save # Resolve provider class. - class_ = provider_settings.get('class_') + class_ = provider_settings.get("class_") if not class_: raise ConfigError( - 'The "class_" key not specified in the config' - ' for provider {0}!'.format(provider_name)) + 'The "class_" key not specified in the config for provider {0}!'.format(provider_name) + ) ProviderClass = resolve_provider_class(class_) # FIXME: Find a nicer solution ProviderClass._logger = self._logger # instantiate provider class - provider = ProviderClass(self, - adapter=adapter, - provider_name=provider_name, - callback=callback, - session=session, - session_saver=session_saver, - **kwargs) + provider = ProviderClass( + self, + adapter=adapter, + provider_name=provider_name, + callback=callback, + session=session, + session_saver=session_saver, + **kwargs, + ) # return login result return provider.login() @@ -1430,8 +1440,9 @@ class Authomatic(object): return Credentials.deserialize(self.config, credentials) - def access(self, credentials, url, params=None, method='GET', - headers=None, body='', max_redirects=5, content_parser=None): + def access( + self, credentials, url, params=None, method="GET", headers=None, body="", max_redirects=5, content_parser=None + ): """ Accesses **protected resource** on behalf of the **user**. @@ -1467,20 +1478,21 @@ class Authomatic(object): # Resolve provider class. ProviderClass = credentials.provider_class - logging.info('ACCESS HEADERS: {0}'.format(headers)) + logging.info("ACCESS HEADERS: {0}".format(headers)) # Access resource and return response. - provider = ProviderClass( - self, adapter=None, provider_name=credentials.provider_name) + provider = ProviderClass(self, adapter=None, provider_name=credentials.provider_name) provider.credentials = credentials - return provider.access(url=url, - params=params, - method=method, - headers=headers, - body=body, - max_redirects=max_redirects, - content_parser=content_parser) + return provider.access( + url=url, + params=params, + method=method, + headers=headers, + body=body, + max_redirects=max_redirects, + content_parser=content_parser, + ) def async_access(self, *args, **kwargs): """ @@ -1499,8 +1511,15 @@ class Authomatic(object): return Future(self.access, *args, **kwargs) def request_elements( - self, credentials=None, url=None, method='GET', params=None, - headers=None, body='', json_input=None, return_json=False + self, + credentials=None, + url=None, + method="GET", + params=None, + headers=None, + body="", + json_input=None, + return_json=False, ): """ Creates request elements for accessing **protected resource of a @@ -1575,17 +1594,18 @@ class Authomatic(object): if json_input: parsed_input = json.loads(json_input) - credentials = parsed_input.get('credentials', credentials) - url = parsed_input.get('url', url) - method = parsed_input.get('method', method) - params = parsed_input.get('params', params) - headers = parsed_input.get('headers', headers) - body = parsed_input.get('body', body) + credentials = parsed_input.get("credentials", credentials) + url = parsed_input.get("url", url) + method = parsed_input.get("method", method) + params = parsed_input.get("params", params) + headers = parsed_input.get("headers", headers) + body = parsed_input.get("body", body) if not credentials and url: raise RequestElementsError( - 'To create request elements, you must provide credentials ' - 'and URL either as keyword arguments or in the JSON object!') + "To create request elements, you must provide credentials " + "and URL either as keyword arguments or in the JSON object!" + ) # Get the provider class credentials = Credentials.deserialize(self.config, credentials) @@ -1599,7 +1619,8 @@ class Authomatic(object): method=method, params=params, headers=headers, - body=body) + body=body, + ) if return_json: return request_elements.to_json() @@ -1693,67 +1714,66 @@ class Authomatic(object): """ - AUTHOMATIC_HEADER = 'Authomatic-Response-To' + AUTHOMATIC_HEADER = "Authomatic-Response-To" # Collect request params - request_type = adapter.params.get('type', 'auto') - json_input = adapter.params.get('json') - credentials = adapter.params.get('credentials') - url = adapter.params.get('url') - method = adapter.params.get('method', 'GET') - body = adapter.params.get('body', '') + request_type = adapter.params.get("type", "auto") + json_input = adapter.params.get("json") + credentials = adapter.params.get("credentials") + url = adapter.params.get("url") + method = adapter.params.get("method", "GET") + body = adapter.params.get("body", "") - params = adapter.params.get('params') + params = adapter.params.get("params") params = json.loads(params) if params else {} - headers = adapter.params.get('headers') + headers = adapter.params.get("headers") headers = json.loads(headers) if headers else {} - ProviderClass = Credentials.deserialize( - self.config, credentials).provider_class + ProviderClass = Credentials.deserialize(self.config, credentials).provider_class - if request_type == 'auto': + if request_type == "auto": # If there is a "callback" param, it's a JSONP request. - jsonp = params.get('callback') + jsonp = params.get("callback") # JSONP is possible only with GET method. - if ProviderClass.supports_jsonp and method == 'GET': - request_type = 'elements' + if ProviderClass.supports_jsonp and method == "GET": + request_type = "elements" else: # Remove the JSONP callback if jsonp: - params.pop('callback') - request_type = 'fetch' + params.pop("callback") + request_type = "fetch" - if request_type == 'fetch': + if request_type == "fetch": # Access protected resource - response = self.access( - credentials, url, params, method, headers, body) + response = self.access(credentials, url, params, method, headers, body) result = response.content # Forward status - adapter.status = str(response.status) + ' ' + str(response.reason) + adapter.status = str(response.status) + " " + str(response.reason) # Forward headers for k, v in response.getheaders(): - logging.info(' {0}: {1}'.format(k, v)) + logging.info(" {0}: {1}".format(k, v)) adapter.set_header(k, v) - elif request_type == 'elements': + elif request_type == "elements": # Create request elements if json_input: - result = self.request_elements( - json_input=json_input, return_json=True) + result = self.request_elements(json_input=json_input, return_json=True) else: - result = self.request_elements(credentials=credentials, - url=url, - method=method, - params=params, - headers=headers, - body=body, - return_json=True) + result = self.request_elements( + credentials=credentials, + url=url, + method=method, + params=params, + headers=headers, + body=body, + return_json=True, + ) - adapter.set_header('Content-Type', 'application/json') + adapter.set_header("Content-Type", "application/json") else: result = '{"error": "Bad Request!"}' diff --git a/rhodecode/lib/_vendor/authomatic/exceptions.py b/rhodecode/lib/_vendor/authomatic/exceptions.py index 0511418b..993b5cf9 100755 --- a/rhodecode/lib/_vendor/authomatic/exceptions.py +++ b/rhodecode/lib/_vendor/authomatic/exceptions.py @@ -1,4 +1,3 @@ - """ Provides various exception types for the library. """ @@ -9,7 +8,7 @@ class BaseError(Exception): Base error for all errors. """ - def __init__(self, message, original_message='', url='', status=None): + def __init__(self, message, original_message="", url="", status=None): super(BaseError, self).__init__(message) #: Error message. diff --git a/rhodecode/lib/_vendor/authomatic/extras/flask.py b/rhodecode/lib/_vendor/authomatic/extras/flask.py index 1d6bd89f..859f57f8 100755 --- a/rhodecode/lib/_vendor/authomatic/extras/flask.py +++ b/rhodecode/lib/_vendor/authomatic/extras/flask.py @@ -1,4 +1,3 @@ - """ |flask| Extras -------------- @@ -33,14 +32,13 @@ class FlaskAuthomatic(Authomatic): def decorated(*args, **kwargs): self.response = make_response() adapter = WerkzeugAdapter(request, self.response) - login_kwargs.setdefault('session', session) - login_kwargs.setdefault('session_saver', self.session_saver) - self.result = super(FlaskAuthomatic, self).login( - adapter, - *login_args, - **login_kwargs) + login_kwargs.setdefault("session", session) + login_kwargs.setdefault("session_saver", self.session_saver) + self.result = super(FlaskAuthomatic, self).login(adapter, *login_args, **login_kwargs) return f(*args, **kwargs) + return decorated + return decorator def session_saver(self): diff --git a/rhodecode/lib/_vendor/authomatic/extras/gae/__init__.py b/rhodecode/lib/_vendor/authomatic/extras/gae/__init__.py index 5e231db5..b4405773 100755 --- a/rhodecode/lib/_vendor/authomatic/extras/gae/__init__.py +++ b/rhodecode/lib/_vendor/authomatic/extras/gae/__init__.py @@ -1,4 +1,3 @@ - """ |gae| Extras ------------ @@ -6,7 +5,6 @@ Utilities you can use when using this library on |gae|_. """ - from authomatic import exceptions from authomatic.extras import interfaces from authomatic.extras.gae.openid import NDBOpenIDStore @@ -21,7 +19,7 @@ except ImportError: logger.exception("FATAL: google.appengine 1st Gen. not installed!") raise -__all__ = ['ndb_config', 'Webapp2Session'] +__all__ = ["ndb_config", "Webapp2Session"] class GAEError(exceptions.BaseError): @@ -41,9 +39,9 @@ class Webapp2Session(interfaces.BaseSession): """ - def __init__(self, handler, session=None, secret=None, - cookie_name='webapp2authomatic', backend='memcache', - config=None): + def __init__( + self, handler, session=None, secret=None, cookie_name="webapp2authomatic", backend="memcache", config=None + ): """ .. warning:: @@ -76,11 +74,10 @@ class Webapp2Session(interfaces.BaseSession): if session is None: if not secret: - raise GAEError('Either session or secret must be specified!') + raise GAEError("Either session or secret must be specified!") else: # Create new session. - cfg = config or dict( - secret_key=secret, cookie_name=cookie_name) + cfg = config or dict(secret_key=secret, cookie_name=cookie_name) session_store = sessions.SessionStore(handler.request, cfg) self.session_dict = session_store.get_session(backend=backend) else: @@ -148,14 +145,14 @@ class NDBConfig(ndb.Model): result_dict = result.to_dict() # Use NDBOpenIDStore by default - result_dict['store'] = NDBOpenIDStore + result_dict["store"] = NDBOpenIDStore # Convert coma-separated values to list. Currently only scope is # csv. - for i in ('scope', ): + for i in ("scope",): prop = result_dict.get(i) if prop: - result_dict[i] = [s.strip() for s in prop.split(',')] + result_dict[i] = [s.strip() for s in prop.split(",")] else: result_dict[i] = None @@ -192,32 +189,30 @@ class NDBConfig(ndb.Model): """ if not len(cls.query().fetch()): + example = cls.get_or_insert("Example") - example = cls.get_or_insert('Example') - - example.class_ = 'Provider class e.g. ' + \ - '"authomatic.providers.oauth2.Facebook".' + example.class_ = "Provider class e.g. " + '"authomatic.providers.oauth2.Facebook".' example.provider_name = 'Your custom provider name e.g. "fb".' # AuthorizationProvider - example.consumer_key = 'Consumer key.' - example.consumer_secret = 'Consumer secret' + example.consumer_key = "Consumer key." + example.consumer_secret = "Consumer secret" example.provider_id = 1 # OAuth2 - example.scope = 'coma, separated, list, of, scopes' + example.scope = "coma, separated, list, of, scopes" # AuthenticationProvider - example.identifier_param = 'Querystring parameter for claimed ' + \ - 'id. default is "id"' + example.identifier_param = "Querystring parameter for claimed " + 'id. default is "id"' # Save the example example.put() # Raise an information error. raise GAEError( - 'A NDBConfig data model was created! Go to Datastore Viewer ' - 'in your dashboard and populate it with data!') + "A NDBConfig data model was created! Go to Datastore Viewer " + "in your dashboard and populate it with data!" + ) def ndb_config(): diff --git a/rhodecode/lib/_vendor/authomatic/extras/gae/openid.py b/rhodecode/lib/_vendor/authomatic/extras/gae/openid.py index 06c45eed..9a11b739 100755 --- a/rhodecode/lib/_vendor/authomatic/extras/gae/openid.py +++ b/rhodecode/lib/_vendor/authomatic/extras/gae/openid.py @@ -1,5 +1,3 @@ - - # We need absolute import to import from openid library which has the same # name as this module from __future__ import absolute_import @@ -40,35 +38,27 @@ class NDBOpenIDStore(ndb.Expando, openid.store.interface.OpenIDStore): lifetime = datetime.timedelta(0, association.lifetime) expiration_date = issued + lifetime - entity = cls.get_or_insert( - association.handle, parent=ndb.Key( - 'ServerUrl', server_url)) + entity = cls.get_or_insert(association.handle, parent=ndb.Key("ServerUrl", server_url)) entity.serialized = association.serialize() entity.expiration_date = expiration_date entity.issued = association.issued - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Putting OpenID association to datastore.') + cls._log(logging.DEBUG, "NDBOpenIDStore: Putting OpenID association to datastore.") entity.put() @classmethod def cleanupAssociations(cls): # query for all expired - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Querying datastore for OpenID associations.') + cls._log(logging.DEBUG, "NDBOpenIDStore: Querying datastore for OpenID associations.") query = cls.query(cls.expiration_date <= datetime.datetime.now()) # fetch keys only expired = query.fetch(keys_only=True) # delete all expired - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Deleting expired OpenID associations from datastore.') + cls._log(logging.DEBUG, "NDBOpenIDStore: Deleting expired OpenID associations from datastore.") ndb.delete_multi(expired) return len(expired) @@ -78,85 +68,57 @@ class NDBOpenIDStore(ndb.Expando, openid.store.interface.OpenIDStore): cls.cleanupAssociations() if handle: - key = ndb.Key('ServerUrl', server_url, cls, handle) - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Getting OpenID association from datastore by key.') + key = ndb.Key("ServerUrl", server_url, cls, handle) + cls._log(logging.DEBUG, "NDBOpenIDStore: Getting OpenID association from datastore by key.") entity = key.get() else: # return most recently issued association - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Querying datastore for OpenID associations by ancestor.') - entity = cls.query(ancestor=ndb.Key( - 'ServerUrl', server_url)).order(-cls.issued).get() + cls._log(logging.DEBUG, "NDBOpenIDStore: Querying datastore for OpenID associations by ancestor.") + entity = cls.query(ancestor=ndb.Key("ServerUrl", server_url)).order(-cls.issued).get() if entity and entity.serialized: - return openid.association.Association.deserialize( - entity.serialized) + return openid.association.Association.deserialize(entity.serialized) @classmethod def removeAssociation(cls, server_url, handle): - key = ndb.Key('ServerUrl', server_url, cls, handle) - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Getting OpenID association from datastore by key.') + key = ndb.Key("ServerUrl", server_url, cls, handle) + cls._log(logging.DEBUG, "NDBOpenIDStore: Getting OpenID association from datastore by key.") if key.get(): - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Deleting OpenID association from datastore.') + cls._log(logging.DEBUG, "NDBOpenIDStore: Deleting OpenID association from datastore.") key.delete() return True @classmethod def useNonce(cls, server_url, timestamp, salt): - # check whether there is already an entity with the same ancestor path # in the datastore - key = ndb.Key( - 'ServerUrl', - str(server_url) or 'x', - 'TimeStamp', - str(timestamp), - cls, - str(salt)) + key = ndb.Key("ServerUrl", str(server_url) or "x", "TimeStamp", str(timestamp), cls, str(salt)) - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Getting OpenID nonce from datastore by key.') + cls._log(logging.DEBUG, "NDBOpenIDStore: Getting OpenID nonce from datastore by key.") result = key.get() if result: # if so, the nonce is not valid so return False - cls._log( - logging.WARNING, - u'NDBOpenIDStore: Nonce was already used!') + cls._log(logging.WARNING, "NDBOpenIDStore: Nonce was already used!") return False else: # if not, store the key to datastore and return True nonce = cls(key=key) - nonce.expiration_date = datetime.datetime.fromtimestamp( - timestamp) + datetime.timedelta(0, openid.store.nonce.SKEW) - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Putting new nonce to datastore.') + nonce.expiration_date = datetime.datetime.fromtimestamp(timestamp) + datetime.timedelta( + 0, openid.store.nonce.SKEW + ) + cls._log(logging.DEBUG, "NDBOpenIDStore: Putting new nonce to datastore.") nonce.put() return True @classmethod def cleanupNonces(cls): # get all expired nonces - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Querying datastore for OpenID nonces ordered by expiration date.') - expired = cls.query().filter( - cls.expiration_date <= datetime.datetime.now()).fetch( - keys_only=True) + cls._log(logging.DEBUG, "NDBOpenIDStore: Querying datastore for OpenID nonces ordered by expiration date.") + expired = cls.query().filter(cls.expiration_date <= datetime.datetime.now()).fetch(keys_only=True) # delete all expired - cls._log( - logging.DEBUG, - u'NDBOpenIDStore: Deleting expired OpenID nonces from datastore.') + cls._log(logging.DEBUG, "NDBOpenIDStore: Deleting expired OpenID nonces from datastore.") ndb.delete_multi(expired) return len(expired) diff --git a/rhodecode/lib/_vendor/authomatic/extras/interfaces.py b/rhodecode/lib/_vendor/authomatic/extras/interfaces.py index dcd63279..64eaef62 100755 --- a/rhodecode/lib/_vendor/authomatic/extras/interfaces.py +++ b/rhodecode/lib/_vendor/authomatic/extras/interfaces.py @@ -1,4 +1,3 @@ - """ Interfaces ^^^^^^^^^^ diff --git a/rhodecode/lib/_vendor/authomatic/providers/__init__.py b/rhodecode/lib/_vendor/authomatic/providers/__init__.py index c3892c10..9113ccba 100755 --- a/rhodecode/lib/_vendor/authomatic/providers/__init__.py +++ b/rhodecode/lib/_vendor/authomatic/providers/__init__.py @@ -1,4 +1,3 @@ - """ Abstract Classes for Providers ------------------------------ @@ -39,11 +38,7 @@ from authomatic.six.moves import urllib_parse as parse from authomatic.six.moves import http_client from authomatic.exceptions import CancellationError -__all__ = [ - 'BaseProvider', - 'AuthorizationProvider', - 'AuthenticationProvider', - 'login_decorator'] +__all__ = ["BaseProvider", "AuthorizationProvider", "AuthenticationProvider", "login_decorator"] def _error_traceback_html(exc_info, traceback_): @@ -94,18 +89,11 @@ def login_decorator(func): if provider.settings.report_errors: error = e if not isinstance(error, CancellationError): - provider._log( - logging.ERROR, - u'Reported suppressed exception: {0}!'.format( - repr(error)), - exc_info=1) + provider._log(logging.ERROR, "Reported suppressed exception: {0}!".format(repr(error)), exc_info=1) else: if provider.settings.debug: # TODO: Check whether it actually works without middleware - provider.write( - _error_traceback_html( - sys.exc_info(), - traceback.format_exc())) + provider.write(_error_traceback_html(sys.exc_info(), traceback.format_exc())) raise # If there is user or error the login procedure has finished @@ -118,7 +106,7 @@ def login_decorator(func): if isinstance(provider.session, authomatic.core.Session): provider.session.delete() - provider._log(logging.INFO, u'Procedure finished.') + provider._log(logging.INFO, "Procedure finished.") if provider.callback: provider.callback(result) @@ -137,16 +125,24 @@ class BaseProvider(object): PROVIDER_TYPE_ID = 0 - _repr_ignore = ('user',) + _repr_ignore = ("user",) __metaclass__ = abc.ABCMeta supported_user_attributes = authomatic.core.SupportedUserAttributes() - def __init__(self, settings, adapter, provider_name, session=None, - session_saver=None, callback=None, js_callback=None, - prefix='authomatic', **kwargs): - + def __init__( + self, + settings, + adapter, + provider_name, + session=None, + session_saver=None, + callback=None, + js_callback=None, + prefix="authomatic", + **kwargs, + ): self.settings = settings self.adapter = adapter @@ -170,7 +166,7 @@ class BaseProvider(object): #: :class:`bool` If ``True``, the #: :attr:`.BaseProvider.user_authorization_url` will be displayed #: in a *popup mode*, if the **provider** supports it. - self.popup = self._kwarg(kwargs, 'popup') + self.popup = self._kwarg(kwargs, "popup") @property def url(self): @@ -190,8 +186,8 @@ class BaseProvider(object): self.adapter.set_status(status) def redirect(self, url): - self.set_status('302 Found') - self.set_header('Location', url) + self.set_status("302 Found") + self.set_header("Location", url) # ======================================================================== # Abstract methods @@ -223,12 +219,14 @@ class BaseProvider(object): """ - return dict(name=self.name, - id=getattr(self, 'id', None), - type_id=self.type_id, - type=self.get_type(), - scope=getattr(self, 'scope', None), - user=self.user.id if self.user else None) + return dict( + name=self.name, + id=getattr(self, "id", None), + type_id=self.type_id, + type=self.get_type(), + scope=getattr(self, "scope", None), + user=self.user.id if self.user else None, + ) @classmethod def get_type(cls): @@ -241,7 +239,7 @@ class BaseProvider(object): """ - return cls.__module__ + '.' + cls.__bases__[0].__name__ + return cls.__module__ + "." + cls.__bases__[0].__name__ def update_user(self): """ @@ -281,10 +279,12 @@ class BaseProvider(object): """ - return kwargs.get(kwname) or \ - self.settings.config.get(self.name, {}).get(kwname) or \ - self.settings.config.get('__defaults__', {}).get(kwname) or \ - default + return ( + kwargs.get(kwname) + or self.settings.config.get(self.name, {}).get(kwname) + or self.settings.config.get("__defaults__", {}).get(kwname) + or default + ) def _session_key(self, key): """ @@ -295,7 +295,7 @@ class BaseProvider(object): """ - return '{0}:{1}:{2}'.format(self.settings.prefix, self.name, key) + return "{0}:{1}:{2}".format(self.settings.prefix, self.name, key) def _session_set(self, key, value): """ @@ -330,7 +330,7 @@ class BaseProvider(object): # Each time return random portion of the hash. span = 5 shift = random.randint(0, span) - return hashed[shift:shift - span - 1] + return hashed[shift : shift - span - 1] @classmethod def _log(cls, level, msg, **kwargs): @@ -347,13 +347,10 @@ class BaseProvider(object): """ - logger = getattr(cls, '_logger', None) or authomatic.core._logger - logger.log( - level, ': '.join( - ('authomatic', cls.__name__, msg)), **kwargs) + logger = getattr(cls, "_logger", None) or authomatic.core._logger + logger.log(level, ": ".join(("authomatic", cls.__name__, msg)), **kwargs) - def _fetch(self, url, method='GET', params=None, headers=None, - body='', max_redirects=5, content_parser=None): + def _fetch(self, url, method="GET", params=None, headers=None, body="", max_redirects=5, content_parser=None): """ Fetches a URL. @@ -391,26 +388,23 @@ class BaseProvider(object): scheme, host, path, query, fragment = parse.urlsplit(url) query = parse.urlencode(params) - if method in ('POST', 'PUT', 'PATCH'): + if method in ("POST", "PUT", "PATCH"): if not body: # Put querystring to body body = query - query = '' - headers.update( - {'Content-Type': 'application/x-www-form-urlencoded'}) - request_path = parse.urlunsplit(('', '', path or '', query or '', '')) + query = "" + headers.update({"Content-Type": "application/x-www-form-urlencoded"}) + request_path = parse.urlunsplit(("", "", path or "", query or "", "")) - self._log(logging.DEBUG, u' \u251C\u2500 host: {0}'.format(host)) - self._log( - logging.DEBUG, - u' \u251C\u2500 path: {0}'.format(request_path)) - self._log(logging.DEBUG, u' \u251C\u2500 method: {0}'.format(method)) - self._log(logging.DEBUG, u' \u251C\u2500 body: {0}'.format(body)) - self._log(logging.DEBUG, u' \u251C\u2500 params: {0}'.format(params)) - self._log(logging.DEBUG, u' \u2514\u2500 headers: {0}'.format(headers)) + self._log(logging.DEBUG, " \u251c\u2500 host: {0}".format(host)) + self._log(logging.DEBUG, " \u251c\u2500 path: {0}".format(request_path)) + self._log(logging.DEBUG, " \u251c\u2500 method: {0}".format(method)) + self._log(logging.DEBUG, " \u251c\u2500 body: {0}".format(body)) + self._log(logging.DEBUG, " \u251c\u2500 params: {0}".format(params)) + self._log(logging.DEBUG, " \u2514\u2500 headers: {0}".format(headers)) # Connect - if scheme.lower() == 'https': + if scheme.lower() == "https": connection = http_client.HTTPSConnection(host) else: connection = http_client.HTTPConnection(host) @@ -418,48 +412,33 @@ class BaseProvider(object): try: connection.request(method, request_path, body, headers) except Exception as e: - raise FetchError('Fetching URL failed', - original_message=str(e), - url=request_path) + raise FetchError("Fetching URL failed", original_message=str(e), url=request_path) response = connection.getresponse() - location = response.getheader('Location') + location = response.getheader("Location") if response.status in (300, 301, 302, 303, 307) and location: if location == url: - raise FetchError('Url redirects to itself!', - url=location, - status=response.status) + raise FetchError("Url redirects to itself!", url=location, status=response.status) elif max_redirects > 0: remaining_redirects = max_redirects - 1 - self._log(logging.DEBUG, u'Redirecting to {0}'.format(url)) - self._log(logging.DEBUG, u'Remaining redirects: {0}' - .format(remaining_redirects)) + self._log(logging.DEBUG, "Redirecting to {0}".format(url)) + self._log(logging.DEBUG, "Remaining redirects: {0}".format(remaining_redirects)) # Call this method again. - response = self._fetch(url=location, - params=params, - method=method, - headers=headers, - max_redirects=remaining_redirects) + response = self._fetch( + url=location, params=params, method=method, headers=headers, max_redirects=remaining_redirects + ) else: - raise FetchError('Max redirects reached!', - url=location, - status=response.status) + raise FetchError("Max redirects reached!", url=location, status=response.status) else: - self._log(logging.DEBUG, u'Got response:') - self._log(logging.DEBUG, u' \u251C\u2500 url: {0}'.format(url)) - self._log( - logging.DEBUG, - u' \u251C\u2500 status: {0}'.format( - response.status)) - self._log( - logging.DEBUG, - u' \u2514\u2500 headers: {0}'.format( - response.getheaders())) + self._log(logging.DEBUG, "Got response:") + self._log(logging.DEBUG, " \u251c\u2500 url: {0}".format(url)) + self._log(logging.DEBUG, " \u251c\u2500 status: {0}".format(response.status)) + self._log(logging.DEBUG, " \u2514\u2500 headers: {0}".format(response.getheaders())) return authomatic.core.Response(response, content_parser) @@ -481,7 +460,7 @@ class BaseProvider(object): # Update. for key in self.user.__dict__: # Exclude data. - if key not in ('data', 'content'): + if key not in ("data", "content"): # Extract every data item whose key matches the user # property name, but only if it has a value. value = data.get(key) @@ -499,19 +478,14 @@ class BaseProvider(object): if not self.user.name: if self.user.first_name and self.user.last_name: # Create it from first name and last name if available. - self.user.name = ' '.join((self.user.first_name, - self.user.last_name)) + self.user.name = " ".join((self.user.first_name, self.user.last_name)) else: # Or use one of these. - self.user.name = (self.user.username - or self.user.nickname - or self.user.first_name - or self.user.last_name) + self.user.name = self.user.username or self.user.nickname or self.user.first_name or self.user.last_name if not self.user.location: if self.user.city and self.user.country: - self.user.location = '{0}, {1}'.format(self.user.city, - self.user.country) + self.user.location = "{0}, {1}".format(self.user.city, self.user.country) else: self.user.location = self.user.city or self.user.country @@ -538,7 +512,7 @@ class BaseProvider(object): hundreds digit. """ - assert category < 10, 'HTTP status category must be a one-digit int!' + assert category < 10, "HTTP status category must be a one-digit int!" cat = category * 100 return status >= cat and status < cat + 100 @@ -559,7 +533,7 @@ class AuthorizationProvider(BaseProvider): PROTECTED_RESOURCE_REQUEST_TYPE = 4 REFRESH_TOKEN_REQUEST_TYPE = 5 - BEARER = 'Bearer' + BEARER = "Bearer" _x_term_dict = {} @@ -611,25 +585,21 @@ class AuthorizationProvider(BaseProvider): super(AuthorizationProvider, self).__init__(*args, **kwargs) - self.consumer_key = self._kwarg(kwargs, 'consumer_key') - self.consumer_secret = self._kwarg(kwargs, 'consumer_secret') + self.consumer_key = self._kwarg(kwargs, "consumer_key") + self.consumer_secret = self._kwarg(kwargs, "consumer_secret") - self.user_authorization_params = self._kwarg( - kwargs, 'user_authorization_params', {}) + self.user_authorization_params = self._kwarg(kwargs, "user_authorization_params", {}) - self.access_token_headers = self._kwarg( - kwargs, 'user_authorization_headers', {}) - self.access_token_params = self._kwarg( - kwargs, 'access_token_params', {}) + self.access_token_headers = self._kwarg(kwargs, "user_authorization_headers", {}) + self.access_token_params = self._kwarg(kwargs, "access_token_params", {}) - self.id = self._kwarg(kwargs, 'id') + self.id = self._kwarg(kwargs, "id") - self.access_headers = self._kwarg(kwargs, 'access_headers', {}) - self.access_params = self._kwarg(kwargs, 'access_params', {}) + self.access_headers = self._kwarg(kwargs, "access_headers", {}) + self.access_params = self._kwarg(kwargs, "access_params", {}) #: :class:`.Credentials` to access **user's protected resources**. - self.credentials = authomatic.core.Credentials( - self.settings.config, provider=self) + self.credentials = authomatic.core.Credentials(self.settings.config, provider=self) #: Response of the *access token request*. self.access_token_response = None @@ -711,9 +681,7 @@ class AuthorizationProvider(BaseProvider): """ @abc.abstractmethod - def create_request_elements(self, request_type, credentials, - url, method='GET', params=None, headers=None, - body=''): + def create_request_elements(self, request_type, credentials, url, method="GET", params=None, headers=None, body=""): """ Must return :class:`.RequestElements`. @@ -769,11 +737,9 @@ class AuthorizationProvider(BaseProvider): cls = self.__class__ mod = sys.modules.get(cls.__module__) - return str(self.PROVIDER_TYPE_ID) + '-' + \ - str(mod.PROVIDER_ID_MAP.index(cls)) + return str(self.PROVIDER_TYPE_ID) + "-" + str(mod.PROVIDER_ID_MAP.index(cls)) - def access(self, url, params=None, method='GET', headers=None, - body='', max_redirects=5, content_parser=None): + def access(self, url, params=None, method="GET", headers=None, body="", max_redirects=5, content_parser=None): """ Fetches the **protected resource** of an authenticated **user**. @@ -805,13 +771,11 @@ class AuthorizationProvider(BaseProvider): """ if not self.user and not self.credentials: - raise CredentialsError(u'There is no authenticated user!') + raise CredentialsError("There is no authenticated user!") headers = headers or {} - self._log( - logging.INFO, - u'Accessing protected resource {0}.'.format(url)) + self._log(logging.INFO, "Accessing protected resource {0}.".format(url)) request_elements = self.create_request_elements( request_type=self.PROTECTED_RESOURCE_REQUEST_TYPE, @@ -820,17 +784,12 @@ class AuthorizationProvider(BaseProvider): body=body, params=params, headers=headers, - method=method + method=method, ) - response = self._fetch(*request_elements, - max_redirects=max_redirects, - content_parser=content_parser) + response = self._fetch(*request_elements, max_redirects=max_redirects, content_parser=content_parser) - self._log( - logging.INFO, - u'Got response. HTTP status = {0}.'.format( - response.status)) + self._log(logging.INFO, "Got response. HTTP status = {0}.".format(response.status)) return response def async_access(self, *args, **kwargs): @@ -861,10 +820,8 @@ class AuthorizationProvider(BaseProvider): """ if self.user_info_url: response = self._access_user_info() - self.user = self._update_or_create_user(response.data, - content=response.content) - return authomatic.core.UserInfoResponse(self.user, - response.httplib_response) + self.user = self._update_or_create_user(response.data, content=response.content) + return authomatic.core.UserInfoResponse(self.user, response.httplib_response) # ======================================================================== # Internal methods @@ -885,11 +842,9 @@ class AuthorizationProvider(BaseProvider): """ if cls._x_use_authorization_header: - res = ':'.join( - (credentials.consumer_key, - credentials.consumer_secret)) + res = ":".join((credentials.consumer_key, credentials.consumer_secret)) res = base64.b64encode(six.b(res)).decode() - return {'Authorization': 'Basic {0}'.format(res)} + return {"Authorization": "Basic {0}".format(res)} else: return {} @@ -901,14 +856,10 @@ class AuthorizationProvider(BaseProvider): # 'magic' using _kwarg method # pylint:disable=no-member if not self.consumer.key: - raise ConfigError( - 'Consumer key not specified for provider {0}!'.format( - self.name)) + raise ConfigError("Consumer key not specified for provider {0}!".format(self.name)) if not self.consumer.secret: - raise ConfigError( - 'Consumer secret not specified for provider {0}!'.format( - self.name)) + raise ConfigError("Consumer secret not specified for provider {0}!".format(self.name)) @staticmethod def _split_url(url): @@ -923,8 +874,7 @@ class AuthorizationProvider(BaseProvider): return base, params @classmethod - def _x_request_elements_filter( - cls, request_type, request_elements, credentials): + def _x_request_elements_filter(cls, request_type, request_elements, credentials): """ Override this to handle special request requirements of zealous providers. @@ -997,14 +947,13 @@ class AuthenticationProvider(BaseProvider): super(AuthenticationProvider, self).__init__(*args, **kwargs) # Lookup default identifier, if available in provider - default_identifier = getattr(self, 'identifier', None) + default_identifier = getattr(self, "identifier", None) # Allow for custom name for the "id" querystring parameter. - self.identifier_param = kwargs.get('identifier_param', 'id') + self.identifier_param = kwargs.get("identifier_param", "id") # Get the identifier from request params, or use default as fallback. - self.identifier = self.params.get( - self.identifier_param, default_identifier) + self.identifier = self.params.get(self.identifier_param, default_identifier) PROVIDER_ID_MAP = [ diff --git a/rhodecode/lib/_vendor/authomatic/providers/gaeopenid.py b/rhodecode/lib/_vendor/authomatic/providers/gaeopenid.py index 600b2bef..1cf6fd1d 100755 --- a/rhodecode/lib/_vendor/authomatic/providers/gaeopenid.py +++ b/rhodecode/lib/_vendor/authomatic/providers/gaeopenid.py @@ -1,4 +1,3 @@ - """ Google App Engine OpenID Providers ---------------------------------- @@ -40,7 +39,7 @@ except ImportError: users = None -__all__ = ['GAEOpenID', 'Yahoo', 'Google'] +__all__ = ["GAEOpenID", "Yahoo", "Google"] class GAEOpenID(providers.AuthenticationProvider): @@ -62,14 +61,11 @@ class GAEOpenID(providers.AuthenticationProvider): # ================================================================= # Phase 1 before redirect. # ================================================================= - self._log( - logging.INFO, - u'Starting OpenID authentication procedure.') + self._log(logging.INFO, "Starting OpenID authentication procedure.") - url = users.create_login_url( - dest_url=self.url, federated_identity=self.identifier) + url = users.create_login_url(dest_url=self.url, federated_identity=self.identifier) - self._log(logging.INFO, u'Redirecting user to {0}.'.format(url)) + self._log(logging.INFO, "Redirecting user to {0}.".format(url)) self.redirect(url) else: @@ -77,27 +73,20 @@ class GAEOpenID(providers.AuthenticationProvider): # Phase 2 after redirect. # ================================================================= - self._log( - logging.INFO, - u'Continuing OpenID authentication procedure after redirect.') + self._log(logging.INFO, "Continuing OpenID authentication procedure after redirect.") user = users.get_current_user() if user: - self._log(logging.INFO, u'Authentication successful.') - self._log(logging.INFO, u'Creating user.') - self.user = core.User(self, - id=user.federated_identity(), - email=user.email(), - gae_user=user) + self._log(logging.INFO, "Authentication successful.") + self._log(logging.INFO, "Creating user.") + self.user = core.User(self, id=user.federated_identity(), email=user.email(), gae_user=user) # ============================================================= # We're done # ============================================================= else: - raise FailureError( - 'Unable to authenticate identifier "{0}"!'.format( - self.identifier)) + raise FailureError('Unable to authenticate identifier "{0}"!'.format(self.identifier)) class Yahoo(GAEOpenID): @@ -106,7 +95,7 @@ class Yahoo(GAEOpenID): ``"me.yahoo.com"``. """ - identifier = 'me.yahoo.com' + identifier = "me.yahoo.com" class Google(GAEOpenID): @@ -115,4 +104,4 @@ class Google(GAEOpenID): ``"https://www.google.com/accounts/o8/id"``. """ - identifier = 'https://www.google.com/accounts/o8/id' + identifier = "https://www.google.com/accounts/o8/id" diff --git a/rhodecode/lib/_vendor/authomatic/providers/oauth1.py b/rhodecode/lib/_vendor/authomatic/providers/oauth1.py index e8948056..00d3c5f2 100755 --- a/rhodecode/lib/_vendor/authomatic/providers/oauth1.py +++ b/rhodecode/lib/_vendor/authomatic/providers/oauth1.py @@ -1,4 +1,3 @@ - """ |oauth1| Providers -------------------- @@ -43,18 +42,18 @@ from authomatic.six.moves import urllib_parse as parse __all__ = [ - 'OAuth1', - 'Bitbucket', - 'Flickr', - 'Meetup', - 'Plurk', - 'Twitter', - 'Tumblr', - 'UbuntuOne', - 'Vimeo', - 'Xero', - 'Xing', - 'Yahoo' + "OAuth1", + "Bitbucket", + "Flickr", + "Meetup", + "Plurk", + "Twitter", + "Tumblr", + "UbuntuOne", + "Vimeo", + "Xero", + "Xing", + "Yahoo", ] @@ -73,23 +72,20 @@ def _normalize_params(params): params = list(params.items()) # remove "realm" and "oauth_signature" - params = sorted([ - (k, v) for k, v in params - if k not in ('oauth_signature', 'realm') - ]) + params = sorted([(k, v) for k, v in params if k not in ("oauth_signature", "realm")]) # sort # convert to query string qs = parse.urlencode(params) # replace "+" to "%20" - qs = qs.replace('+', '%20') + qs = qs.replace("+", "%20") # replace "%7E" to "%20" - qs = qs.replace('%7E', '~') + qs = qs.replace("%7E", "~") return qs def _join_by_ampersand(*args): - return '&'.join([core.escape(i) for i in args]) + return "&".join([core.escape(i) for i in args]) def _create_base_string(method, base, params): @@ -110,11 +106,10 @@ class BaseSignatureGenerator(object): __metaclass__ = abc.ABCMeta #: :class:`str` The name of the signature method. - method = '' + method = "" @abc.abstractmethod - def create_signature(self, method, base, params, - consumer_secret, token_secret=''): + def create_signature(self, method, base, params, consumer_secret, token_secret=""): """ Must create signature based on the parameters as specified in http://oauth.net/core/1.0a/#signing_process. @@ -153,10 +148,10 @@ class HMACSHA1SignatureGenerator(BaseSignatureGenerator): """ - method = 'HMAC-SHA1' + method = "HMAC-SHA1" @classmethod - def _create_key(cls, consumer_secret, token_secret=''): + def _create_key(cls, consumer_secret, token_secret=""): """ Returns a key for HMAC-SHA1 signature as specified at: http://oauth.net/core/1.0a/#rfc.section.9.2. @@ -173,11 +168,10 @@ class HMACSHA1SignatureGenerator(BaseSignatureGenerator): """ - return _join_by_ampersand(consumer_secret, token_secret or '') + return _join_by_ampersand(consumer_secret, token_secret or "") @classmethod - def create_signature(cls, method, base, params, - consumer_secret, token_secret=''): + def create_signature(cls, method, base, params, consumer_secret, token_secret=""): """ Returns HMAC-SHA1 signature as specified at: http://oauth.net/core/1.0a/#rfc.section.9.2. @@ -206,10 +200,7 @@ class HMACSHA1SignatureGenerator(BaseSignatureGenerator): base_string = _create_base_string(method, base, params) key = cls._create_key(consumer_secret, token_secret) - hashed = hmac.new( - six.b(key), - base_string.encode('utf-8'), - hashlib.sha1) + hashed = hmac.new(six.b(key), base_string.encode("utf-8"), hashlib.sha1) base64_encoded = binascii.b2a_base64(hashed.digest())[:-1] @@ -224,16 +215,14 @@ class PLAINTEXTSignatureGenerator(BaseSignatureGenerator): """ - method = 'PLAINTEXT' + method = "PLAINTEXT" @classmethod - def create_signature(cls, method, base, params, - consumer_secret, token_secret=''): + def create_signature(cls, method, base, params, consumer_secret, token_secret=""): + consumer_secret = parse.quote(consumer_secret, "") + token_secret = parse.quote(token_secret, "") - consumer_secret = parse.quote(consumer_secret, '') - token_secret = parse.quote(token_secret, '') - - return parse.quote('&'.join((consumer_secret, token_secret)), '') + return parse.quote("&".join((consumer_secret, token_secret)), "") class OAuth1(providers.AuthorizationProvider): @@ -277,8 +266,7 @@ class OAuth1(providers.AuthorizationProvider): super(OAuth1, self).__init__(*args, **kwargs) - self.request_token_params = self._kwarg( - kwargs, 'request_token_params', {}) + self.request_token_params = self._kwarg(kwargs, "request_token_params", {}) # ======================================================================== # Abstract properties @@ -297,8 +285,7 @@ class OAuth1(providers.AuthorizationProvider): @classmethod def create_request_elements( - cls, request_type, credentials, url, params=None, headers=None, - body='', method='GET', verifier='', callback='' + cls, request_type, credentials, url, params=None, headers=None, body="", method="GET", verifier="", callback="" ): """ Creates |oauth1| request elements. @@ -307,10 +294,10 @@ class OAuth1(providers.AuthorizationProvider): params = params or {} headers = headers or {} - consumer_key = credentials.consumer_key or '' - consumer_secret = credentials.consumer_secret or '' - token = credentials.token or '' - token_secret = credentials.token_secret or '' + consumer_key = credentials.consumer_key or "" + consumer_secret = credentials.consumer_secret or "" + token = credentials.token or "" + token_secret = credentials.token_secret or "" # separate url base and query parameters url, base_params = cls._split_url(url) @@ -321,66 +308,66 @@ class OAuth1(providers.AuthorizationProvider): if request_type == cls.USER_AUTHORIZATION_REQUEST_TYPE: # no need for signature if token: - params['oauth_token'] = token + params["oauth_token"] = token else: - raise OAuth1Error( - 'Credentials with valid token are required to create ' - 'User Authorization URL!') + raise OAuth1Error("Credentials with valid token are required to create User Authorization URL!") else: # signature needed if request_type == cls.REQUEST_TOKEN_REQUEST_TYPE: # Request Token URL if consumer_key and consumer_secret and callback: - params['oauth_consumer_key'] = consumer_key - params['oauth_callback'] = callback + params["oauth_consumer_key"] = consumer_key + params["oauth_callback"] = callback else: raise OAuth1Error( - 'Credentials with valid consumer_key, consumer_secret ' - 'and callback are required to create Request Token ' - 'URL!') + "Credentials with valid consumer_key, consumer_secret " + "and callback are required to create Request Token " + "URL!" + ) elif request_type == cls.ACCESS_TOKEN_REQUEST_TYPE: # Access Token URL if consumer_key and consumer_secret and token and verifier: - params['oauth_token'] = token - params['oauth_consumer_key'] = consumer_key - params['oauth_verifier'] = verifier + params["oauth_token"] = token + params["oauth_consumer_key"] = consumer_key + params["oauth_verifier"] = verifier else: raise OAuth1Error( - 'Credentials with valid consumer_key, ' - 'consumer_secret, token and argument verifier' - ' are required to create Access Token URL!') + "Credentials with valid consumer_key, " + "consumer_secret, token and argument verifier" + " are required to create Access Token URL!" + ) elif request_type == cls.PROTECTED_RESOURCE_REQUEST_TYPE: # Protected Resources URL if consumer_key and consumer_secret and token and token_secret: - params['oauth_token'] = token - params['oauth_consumer_key'] = consumer_key + params["oauth_token"] = token + params["oauth_consumer_key"] = consumer_key else: raise OAuth1Error( - 'Credentials with valid consumer_key, ' - 'consumer_secret, token and token_secret are required ' - 'to create Protected Resources URL!') + "Credentials with valid consumer_key, " + "consumer_secret, token and token_secret are required " + "to create Protected Resources URL!" + ) # Sign request. # http://oauth.net/core/1.0a/#anchor13 # Prepare parameters for signature base string # http://oauth.net/core/1.0a/#rfc.section.9.1 - params['oauth_signature_method'] = cls._signature_generator.method - params['oauth_timestamp'] = str(int(time.time())) - params['oauth_nonce'] = cls.csrf_generator(str(uuid.uuid4())) - params['oauth_version'] = '1.0' + params["oauth_signature_method"] = cls._signature_generator.method + params["oauth_timestamp"] = str(int(time.time())) + params["oauth_nonce"] = cls.csrf_generator(str(uuid.uuid4())) + params["oauth_version"] = "1.0" # add signature to params - params['oauth_signature'] = cls._signature_generator.create_signature( # noqa - method, url, params, consumer_secret, token_secret) + params["oauth_signature"] = cls._signature_generator.create_signature( # noqa + method, url, params, consumer_secret, token_secret + ) - request_elements = core.RequestElements( - url, method, params, headers, body) + request_elements = core.RequestElements(url, method, params, headers, body) - return cls._x_request_elements_filter( - request_type, request_elements, credentials) + return cls._x_request_elements_filter(request_type, request_elements, credentials) # ======================================================================== # Exposed methods @@ -392,39 +379,31 @@ class OAuth1(providers.AuthorizationProvider): @classmethod def reconstruct(cls, deserialized_tuple, credentials, cfg): - token, token_secret = deserialized_tuple credentials.token = token credentials.token_secret = token_secret - credentials.consumer_key = cfg.get('consumer_key', '') - credentials.consumer_secret = cfg.get('consumer_secret', '') + credentials.consumer_key = cfg.get("consumer_key", "") + credentials.consumer_secret = cfg.get("consumer_secret", "") return credentials @providers.login_decorator def login(self): # get request parameters from which we can determine the login phase - denied = self.params.get('denied') - verifier = self.params.get('oauth_verifier', '') - request_token = self.params.get('oauth_token', '') + denied = self.params.get("denied") + verifier = self.params.get("oauth_verifier", "") + request_token = self.params.get("oauth_token", "") if request_token and verifier: # Phase 2 after redirect with success - self._log( - logging.INFO, - u'Continuing OAuth 1.0a authorization procedure after ' - u'redirect.') - token_secret = self._session_get('token_secret') + self._log(logging.INFO, "Continuing OAuth 1.0a authorization procedure after redirect.") + token_secret = self._session_get("token_secret") if not token_secret: - raise FailureError( - u'Unable to retrieve token secret from storage!') + raise FailureError("Unable to retrieve token secret from storage!") # Get Access Token - self._log( - logging.INFO, - u'Fetching for access token from {0}.'.format( - self.access_token_url)) + self._log(logging.INFO, "Fetching for access token from {0}.".format(self.access_token_url)) self.credentials.token = request_token self.credentials.token_secret = token_secret @@ -434,7 +413,7 @@ class OAuth1(providers.AuthorizationProvider): url=self.access_token_url, credentials=self.credentials, verifier=verifier, - params=self.access_token_params + params=self.access_token_params, ) response = self._fetch(*request_elements) @@ -442,22 +421,19 @@ class OAuth1(providers.AuthorizationProvider): if not self._http_status_in_category(response.status, 2): raise FailureError( - 'Failed to obtain OAuth 1.0a oauth_token from {0}! ' - 'HTTP status code: {1}.' - .format(self.access_token_url, response.status), + "Failed to obtain OAuth 1.0a oauth_token from {0}! HTTP status code: {1}.".format( + self.access_token_url, response.status + ), original_message=response.content, status=response.status, - url=self.access_token_url + url=self.access_token_url, ) - self._log(logging.INFO, u'Got access token.') - self.credentials.token = response.data.get('oauth_token', '') - self.credentials.token_secret = response.data.get( - 'oauth_token_secret', '' - ) + self._log(logging.INFO, "Got access token.") + self.credentials.token = response.data.get("oauth_token", "") + self.credentials.token_secret = response.data.get("oauth_token_secret", "") - self.credentials = self._x_credentials_parser(self.credentials, - response.data) + self.credentials = self._x_credentials_parser(self.credentials, response.data) self._update_or_create_user(response.data, self.credentials) # ================================================================= @@ -467,15 +443,15 @@ class OAuth1(providers.AuthorizationProvider): elif denied: # Phase 2 after redirect denied raise CancellationError( - 'User denied the request token {0} during a redirect' - 'to {1}!'.format(denied, self.user_authorization_url), + "User denied the request token {0} during a redirectto {1}!".format( + denied, self.user_authorization_url + ), original_message=denied, - url=self.user_authorization_url) + url=self.user_authorization_url, + ) else: # Phase 1 before redirect - self._log( - logging.INFO, - u'Starting OAuth 1.0a authorization procedure.') + self._log(logging.INFO, "Starting OAuth 1.0a authorization procedure.") # Fetch for request token request_elements = self.create_request_elements( @@ -483,66 +459,59 @@ class OAuth1(providers.AuthorizationProvider): credentials=self.credentials, url=self.request_token_url, callback=self.url, - params=self.request_token_params + params=self.request_token_params, ) - self._log( - logging.INFO, - u'Fetching for request token and token secret.') + self._log(logging.INFO, "Fetching for request token and token secret.") response = self._fetch(*request_elements) # check if response status is OK if not self._http_status_in_category(response.status, 2): raise FailureError( - u'Failed to obtain request token from {0}! HTTP status ' - u'code: {1} content: {2}'.format( - self.request_token_url, - response.status, - response.content + "Failed to obtain request token from {0}! HTTP status code: {1} content: {2}".format( + self.request_token_url, response.status, response.content ), original_message=response.content, status=response.status, - url=self.request_token_url) + url=self.request_token_url, + ) # extract request token - request_token = response.data.get('oauth_token') + request_token = response.data.get("oauth_token") if not request_token: raise FailureError( - 'Response from {0} doesn\'t contain oauth_token ' - 'parameter!'.format(self.request_token_url), + "Response from {0} doesn't contain oauth_token parameter!".format(self.request_token_url), original_message=response.content, - url=self.request_token_url) + url=self.request_token_url, + ) # we need request token for user authorization redirect self.credentials.token = request_token # extract token secret and save it to storage - token_secret = response.data.get('oauth_token_secret') + token_secret = response.data.get("oauth_token_secret") if token_secret: # we need token secret after user authorization redirect to get # access token - self._session_set('token_secret', token_secret) + self._session_set("token_secret", token_secret) else: raise FailureError( - u'Failed to obtain token secret from {0}!'.format( - self.request_token_url), + "Failed to obtain token secret from {0}!".format(self.request_token_url), original_message=response.content, - url=self.request_token_url) + url=self.request_token_url, + ) - self._log(logging.INFO, u'Got request token and token secret') + self._log(logging.INFO, "Got request token and token secret") # Create User Authorization URL request_elements = self.create_request_elements( request_type=self.USER_AUTHORIZATION_REQUEST_TYPE, credentials=self.credentials, url=self.user_authorization_url, - params=self.user_authorization_params + params=self.user_authorization_params, ) - self._log( - logging.INFO, - u'Redirecting user to {0}.'.format( - request_elements.full_url)) + self._log(logging.INFO, "Redirecting user to {0}.".format(request_elements.full_url)) self.redirect(request_elements.full_url) @@ -589,33 +558,24 @@ class Bitbucket(OAuth1): """ supported_user_attributes = core.SupportedUserAttributes( - first_name=True, - id=True, - last_name=True, - link=True, - name=True, - picture=True, - username=True, - email=True + first_name=True, id=True, last_name=True, link=True, name=True, picture=True, username=True, email=True ) - request_token_url = 'https://bitbucket.org/!api/1.0/oauth/request_token' - user_authorization_url = 'https://bitbucket.org/!api/1.0/oauth/' + \ - 'authenticate' - access_token_url = 'https://bitbucket.org/!api/1.0/oauth/access_token' - user_info_url = 'https://api.bitbucket.org/1.0/user' - user_email_url = 'https://api.bitbucket.org/1.0/emails' + request_token_url = "https://bitbucket.org/!api/1.0/oauth/request_token" + user_authorization_url = "https://bitbucket.org/!api/1.0/oauth/" + "authenticate" + access_token_url = "https://bitbucket.org/!api/1.0/oauth/access_token" + user_info_url = "https://api.bitbucket.org/1.0/user" + user_email_url = "https://api.bitbucket.org/1.0/emails" @staticmethod def _x_user_parser(user, data): - _user = data.get('user', {}) - user.username = user.id = _user.get('username') - user.name = _user.get('display_name') - user.first_name = _user.get('first_name') - user.last_name = _user.get('last_name') - user.picture = _user.get('avatar') - user.link = 'https://bitbucket.org/api{0}'\ - .format(_user.get('resource_uri')) + _user = data.get("user", {}) + user.username = user.id = _user.get("username") + user.name = _user.get("display_name") + user.first_name = _user.get("first_name") + user.last_name = _user.get("last_name") + user.picture = _user.get("avatar") + user.link = "https://bitbucket.org/api{0}".format(_user.get("resource_uri")) return user def _access_user_info(self): @@ -689,26 +649,21 @@ class Flickr(OAuth1): """ - supported_user_attributes = core.SupportedUserAttributes( - id=True, - name=True, - username=True - ) + supported_user_attributes = core.SupportedUserAttributes(id=True, name=True, username=True) - request_token_url = 'http://www.flickr.com/services/oauth/request_token' - user_authorization_url = 'http://www.flickr.com/services/oauth/authorize' - access_token_url = 'http://www.flickr.com/services/oauth/access_token' + request_token_url = "http://www.flickr.com/services/oauth/request_token" + user_authorization_url = "http://www.flickr.com/services/oauth/authorize" + access_token_url = "http://www.flickr.com/services/oauth/access_token" user_info_url = None supports_jsonp = True @staticmethod def _x_user_parser(user, data): - _user = data.get('user', {}) + _user = data.get("user", {}) - user.name = data.get('fullname') or _user.get( - 'username', {}).get('_content') - user.id = data.get('user_nsid') or _user.get('id') + user.name = data.get("fullname") or _user.get("username", {}).get("_content") + user.id = data.get("user_nsid") or _user.get("id") return user @@ -754,27 +709,19 @@ class Meetup(OAuth1): """ supported_user_attributes = core.SupportedUserAttributes( - city=True, - country=True, - id=True, - link=True, - locale=True, - location=True, - name=True, - picture=True + city=True, country=True, id=True, link=True, locale=True, location=True, name=True, picture=True ) - request_token_url = 'https://api.meetup.com/oauth/request/' - user_authorization_url = 'http://www.meetup.com/authorize/' - access_token_url = 'https://api.meetup.com/oauth/access/' - user_info_url = 'https://api.meetup.com/2/member/{id}' + request_token_url = "https://api.meetup.com/oauth/request/" + user_authorization_url = "http://www.meetup.com/authorize/" + access_token_url = "https://api.meetup.com/oauth/access/" + user_info_url = "https://api.meetup.com/2/member/{id}" @staticmethod def _x_user_parser(user, data): - - user.id = data.get('id') or data.get('member_id') - user.locale = data.get('lang') - user.picture = data.get('photo', {}).get('photo_link') + user.id = data.get("id") or data.get("member_id") + user.locale = data.get("lang") + user.picture = data.get("photo", {}).get("photo_link") return user @@ -828,42 +775,38 @@ class Plurk(OAuth1): nickname=True, picture=True, timezone=True, - username=True + username=True, ) - request_token_url = 'http://www.plurk.com/OAuth/request_token' - user_authorization_url = 'http://www.plurk.com/OAuth/authorize' - access_token_url = 'http://www.plurk.com/OAuth/access_token' - user_info_url = 'http://www.plurk.com/APP/Profile/getOwnProfile' + request_token_url = "http://www.plurk.com/OAuth/request_token" + user_authorization_url = "http://www.plurk.com/OAuth/authorize" + access_token_url = "http://www.plurk.com/OAuth/access_token" + user_info_url = "http://www.plurk.com/APP/Profile/getOwnProfile" @staticmethod def _x_user_parser(user, data): + _user = data.get("user_info", {}) - _user = data.get('user_info', {}) + user.email = _user.get("email") + user.gender = _user.get("gender") + user.id = _user.get("id") or _user.get("uid") + user.locale = _user.get("default_lang") + user.name = _user.get("full_name") + user.nickname = _user.get("nick_name") + user.picture = "http://avatars.plurk.com/{0}-big2.jpg".format(user.id) + user.timezone = _user.get("timezone") + user.username = _user.get("display_name") - user.email = _user.get('email') - user.gender = _user.get('gender') - user.id = _user.get('id') or _user.get('uid') - user.locale = _user.get('default_lang') - user.name = _user.get('full_name') - user.nickname = _user.get('nick_name') - user.picture = 'http://avatars.plurk.com/{0}-big2.jpg'.format(user.id) - user.timezone = _user.get('timezone') - user.username = _user.get('display_name') + user.link = "http://www.plurk.com/{0}/".format(user.username) - user.link = 'http://www.plurk.com/{0}/'.format(user.username) - - user.city, user.country = _user.get('location', ',').split(',') + user.city, user.country = _user.get("location", ",").split(",") user.city = user.city.strip() user.country = user.country.strip() - _bd = _user.get('date_of_birth') + _bd = _user.get("date_of_birth") if _bd: try: - user.birth_date = datetime.datetime.strptime( - _bd, - "%a, %d %b %Y %H:%M:%S %Z" - ) + user.birth_date = datetime.datetime.strptime(_bd, "%a, %d %b %Y %H:%M:%S %Z") except ValueError: pass @@ -921,29 +864,28 @@ class Twitter(OAuth1): location=True, name=True, picture=True, - username=True + username=True, ) - request_token_url = 'https://api.twitter.com/oauth/request_token' - user_authorization_url = 'https://api.twitter.com/oauth/authenticate' - access_token_url = 'https://api.twitter.com/oauth/access_token' + request_token_url = "https://api.twitter.com/oauth/request_token" + user_authorization_url = "https://api.twitter.com/oauth/authenticate" + access_token_url = "https://api.twitter.com/oauth/access_token" user_info_url = ( - 'https://api.twitter.com/1.1/account/verify_credentials.json?' - 'include_entities=true&include_email=true' + "https://api.twitter.com/1.1/account/verify_credentials.json?include_entities=true&include_email=true" ) supports_jsonp = True @staticmethod def _x_user_parser(user, data): - user.username = data.get('screen_name') - user.id = data.get('id') or data.get('user_id') - user.picture = data.get('profile_image_url') - user.locale = data.get('lang') - user.link = data.get('url') - _location = data.get('location', '') + user.username = data.get("screen_name") + user.id = data.get("id") or data.get("user_id") + user.picture = data.get("profile_image_url") + user.locale = data.get("lang") + user.link = data.get("url") + _location = data.get("location", "") if _location: user.location = _location.strip() - _split_location = _location.split(',') + _split_location = _location.split(",") if len(_split_location) > 1: _city, _country = _split_location user.country = _country.strip() @@ -987,23 +929,19 @@ class Tumblr(OAuth1): """ - supported_user_attributes = core.SupportedUserAttributes( - id=True, - name=True, - username=True - ) + supported_user_attributes = core.SupportedUserAttributes(id=True, name=True, username=True) - request_token_url = 'http://www.tumblr.com/oauth/request_token' - user_authorization_url = 'http://www.tumblr.com/oauth/authorize' - access_token_url = 'http://www.tumblr.com/oauth/access_token' - user_info_url = 'http://api.tumblr.com/v2/user/info' + request_token_url = "http://www.tumblr.com/oauth/request_token" + user_authorization_url = "http://www.tumblr.com/oauth/authorize" + access_token_url = "http://www.tumblr.com/oauth/access_token" + user_info_url = "http://api.tumblr.com/v2/user/info" supports_jsonp = True @staticmethod def _x_user_parser(user, data): - _user = data.get('response', {}).get('user', {}) - user.username = user.id = _user.get('name') + _user = data.get("response", {}).get("user", {}) + user.username = user.id = _user.get("name") return user @@ -1030,10 +968,10 @@ class UbuntuOne(OAuth1): _signature_generator = PLAINTEXTSignatureGenerator - request_token_url = 'https://one.ubuntu.com/oauth/request/' - user_authorization_url = 'https://one.ubuntu.com/oauth/authorize/' - access_token_url = 'https://one.ubuntu.com/oauth/access/' - user_info_url = 'https://one.ubuntu.com/api/account/' + request_token_url = "https://one.ubuntu.com/oauth/request/" + user_authorization_url = "https://one.ubuntu.com/oauth/authorize/" + access_token_url = "https://one.ubuntu.com/oauth/access/" + user_info_url = "https://one.ubuntu.com/api/account/" class Vimeo(OAuth1): @@ -1074,19 +1012,12 @@ class Vimeo(OAuth1): """ - supported_user_attributes = core.SupportedUserAttributes( - id=True, - link=True, - location=True, - name=True, - picture=True - ) + supported_user_attributes = core.SupportedUserAttributes(id=True, link=True, location=True, name=True, picture=True) - request_token_url = 'https://vimeo.com/oauth/request_token' - user_authorization_url = 'https://vimeo.com/oauth/authorize' - access_token_url = 'https://vimeo.com/oauth/access_token' - user_info_url = ('http://vimeo.com/api/rest/v2?' - 'format=json&method=vimeo.oauth.checkAccessToken') + request_token_url = "https://vimeo.com/oauth/request_token" + user_authorization_url = "https://vimeo.com/oauth/authorize" + access_token_url = "https://vimeo.com/oauth/access_token" + user_info_url = "http://vimeo.com/api/rest/v2?format=json&method=vimeo.oauth.checkAccessToken" def _access_user_info(self): """ @@ -1094,17 +1025,16 @@ class Vimeo(OAuth1): to make two requests: one to get user ID and second to get user info. """ response = super(Vimeo, self)._access_user_info() - uid = response.data.get('oauth', {}).get('user', {}).get('id') + uid = response.data.get("oauth", {}).get("user", {}).get("id") if uid: - return self.access('http://vimeo.com/api/v2/{0}/info.json' - .format(uid)) + return self.access("http://vimeo.com/api/v2/{0}/info.json".format(uid)) return response @staticmethod def _x_user_parser(user, data): - user.name = data.get('display_name') - user.link = data.get('profile_url') - user.picture = data.get('portrait_huge') + user.name = data.get("display_name") + user.link = data.get("profile_url") + user.picture = data.get("portrait_huge") return user @@ -1147,28 +1077,24 @@ class Xero(OAuth1): """ supported_user_attributes = core.SupportedUserAttributes( - email=True, - first_name=True, - id=True, - last_name=True, - name=True + email=True, first_name=True, id=True, last_name=True, name=True ) - request_token_url = 'https://api.xero.com/oauth/RequestToken' - user_authorization_url = 'https://api.xero.com/oauth/Authorize' - access_token_url = 'https://api.xero.com/oauth/AccessToken' - user_info_url = 'https://api.xero.com/api.xro/2.0/Users' + request_token_url = "https://api.xero.com/oauth/RequestToken" + user_authorization_url = "https://api.xero.com/oauth/Authorize" + access_token_url = "https://api.xero.com/oauth/AccessToken" + user_info_url = "https://api.xero.com/api.xro/2.0/Users" @staticmethod def _x_user_parser(user, data): # Data is xml.etree.ElementTree.Element object. if not isinstance(data, dict): # But only on user.update() - _user = data.find('Users/User') - user.id = _user.find('UserID').text - user.first_name = _user.find('FirstName').text - user.last_name = _user.find('LastName').text - user.email = _user.find('EmailAddress').text + _user = data.find("Users/User") + user.id = _user.find("UserID").text + user.first_name = _user.find("FirstName").text + user.last_name = _user.find("LastName").text + user.email = _user.find("EmailAddress").text return user @@ -1206,24 +1132,14 @@ class Yahoo(OAuth1): """ supported_user_attributes = core.SupportedUserAttributes( - city=True, - country=True, - id=True, - link=True, - location=True, - name=True, - nickname=True, - picture=True + city=True, country=True, id=True, link=True, location=True, name=True, nickname=True, picture=True ) - request_token_url = 'https://api.login.yahoo.com/oauth/v2/' + \ - 'get_request_token' - user_authorization_url = 'https://api.login.yahoo.com/oauth/v2/' + \ - 'request_auth' - access_token_url = 'https://api.login.yahoo.com/oauth/v2/get_token' + request_token_url = "https://api.login.yahoo.com/oauth/v2/" + "get_request_token" + user_authorization_url = "https://api.login.yahoo.com/oauth/v2/" + "request_auth" + access_token_url = "https://api.login.yahoo.com/oauth/v2/get_token" user_info_url = ( - 'https://query.yahooapis.com/v1/yql?q=select%20*%20from%20' - 'social.profile%20where%20guid%3Dme%3B&format=json' + "https://query.yahooapis.com/v1/yql?q=select%20*%20from%20social.profile%20where%20guid%3Dme%3B&format=json" ) same_origin = False @@ -1231,26 +1147,25 @@ class Yahoo(OAuth1): @staticmethod def _x_user_parser(user, data): + _user = data.get("query", {}).get("results", {}).get("profile", {}) - _user = data.get('query', {}).get('results', {}).get('profile', {}) + user.id = _user.get("guid") + user.gender = _user.get("gender") + user.nickname = _user.get("nickname") + user.link = _user.get("profileUrl") - user.id = _user.get('guid') - user.gender = _user.get('gender') - user.nickname = _user.get('nickname') - user.link = _user.get('profileUrl') - - emails = _user.get('emails') + emails = _user.get("emails") if isinstance(emails, list): for email in emails: - if 'primary' in list(email.keys()): - user.email = email.get('handle') + if "primary" in list(email.keys()): + user.email = email.get("handle") elif isinstance(emails, dict): - user.email = emails.get('handle') + user.email = emails.get("handle") - user.picture = _user.get('image', {}).get('imageUrl') + user.picture = _user.get("image", {}).get("imageUrl") try: - user.city, user.country = _user.get('location', ',').split(',') + user.city, user.country = _user.get("location", ",").split(",") user.city = user.city.strip() user.country = user.country.strip() except ValueError: @@ -1294,10 +1209,10 @@ class Xing(OAuth1): """ - request_token_url = 'https://api.xing.com/v1/request_token' - user_authorization_url = 'https://api.xing.com/v1/authorize' - access_token_url = 'https://api.xing.com/v1/access_token' - user_info_url = 'https://api.xing.com/v1/users/me' + request_token_url = "https://api.xing.com/v1/request_token" + user_authorization_url = "https://api.xing.com/v1/authorize" + access_token_url = "https://api.xing.com/v1/access_token" + user_info_url = "https://api.xing.com/v1/users/me" supported_user_attributes = core.SupportedUserAttributes( birth_date=True, @@ -1321,37 +1236,35 @@ class Xing(OAuth1): @staticmethod def _x_user_parser(user, data): - _users = data.get('users', []) + _users = data.get("users", []) if _users and _users[0]: _user = _users[0] - user.id = _user.get('id') - user.name = _user.get('display_name') - user.first_name = _user.get('first_name') - user.last_name = _user.get('last_name') - user.gender = _user.get('gender') - user.timezone = _user.get('time_zone', {}).get('name') - user.email = _user.get('active_email') - user.link = _user.get('permalink') - user.username = _user.get('page_name') - user.picture = _user.get('photo_urls', {}).get('large') + user.id = _user.get("id") + user.name = _user.get("display_name") + user.first_name = _user.get("first_name") + user.last_name = _user.get("last_name") + user.gender = _user.get("gender") + user.timezone = _user.get("time_zone", {}).get("name") + user.email = _user.get("active_email") + user.link = _user.get("permalink") + user.username = _user.get("page_name") + user.picture = _user.get("photo_urls", {}).get("large") - _address = _user.get('business_address', {}) + _address = _user.get("business_address", {}) if _address: - user.city = _address.get('city') - user.country = _address.get('country') - user.postal_code = _address.get('zip_code') - user.phone = ( - _address.get('phone', '') or - _address.get('mobile_phone', '')).replace('|', '') + user.city = _address.get("city") + user.country = _address.get("country") + user.postal_code = _address.get("zip_code") + user.phone = (_address.get("phone", "") or _address.get("mobile_phone", "")).replace("|", "") - _languages = list(_user.get('languages', {}).keys()) + _languages = list(_user.get("languages", {}).keys()) if _languages and _languages[0]: user.locale = _languages[0] - _birth_date = _user.get('birth_date', {}) - _year = _birth_date.get('year') - _month = _birth_date.get('month') - _day = _birth_date.get('day') + _birth_date = _user.get("birth_date", {}) + _year = _birth_date.get("year") + _month = _birth_date.get("month") + _day = _birth_date.get("day") if _year and _month and _day: user.birth_date = datetime.datetime(_year, _month, _day) diff --git a/rhodecode/lib/_vendor/authomatic/providers/oauth2.py b/rhodecode/lib/_vendor/authomatic/providers/oauth2.py index bfa65958..86e01f9a 100755 --- a/rhodecode/lib/_vendor/authomatic/providers/oauth2.py +++ b/rhodecode/lib/_vendor/authomatic/providers/oauth2.py @@ -1,4 +1,3 @@ - """ |oauth2| Providers ------------------- @@ -43,27 +42,27 @@ import authomatic.core as core __all__ = [ - 'OAuth2', - 'Amazon', - 'Behance', - 'Bitly', - 'Bitbucket', - 'Cosm', - 'DeviantART', - 'Eventbrite', - 'Facebook', - 'Foursquare', - 'GitHub', - 'Google', - 'LinkedIn', - 'MicrosoftOnline', - 'PayPal', - 'Reddit', - 'Viadeo', - 'VK', - 'WindowsLive', - 'Yammer', - 'Yandex' + "OAuth2", + "Amazon", + "Behance", + "Bitly", + "Bitbucket", + "Cosm", + "DeviantART", + "Eventbrite", + "Facebook", + "Foursquare", + "GitHub", + "Google", + "LinkedIn", + "MicrosoftOnline", + "PayPal", + "Reddit", + "Viadeo", + "VK", + "WindowsLive", + "Yammer", + "Yandex", ] @@ -73,7 +72,7 @@ class OAuth2(providers.AuthorizationProvider): """ PROVIDER_TYPE_ID = 2 - TOKEN_TYPES = ['', 'Bearer'] + TOKEN_TYPES = ["", "Bearer"] #: A scope preset to get most of the **user** info. #: Use it in the :doc:`config` like @@ -87,7 +86,7 @@ class OAuth2(providers.AuthorizationProvider): #: :class:`bool` If ``False``, the provider doesn't support user_state. supports_user_state = True - token_request_method = 'POST' # method for requesting an access token + token_request_method = "POST" # method for requesting an access token def __init__(self, *args, **kwargs): """ @@ -110,8 +109,8 @@ class OAuth2(providers.AuthorizationProvider): super(OAuth2, self).__init__(*args, **kwargs) - self.scope = self._kwarg(kwargs, 'scope', []) - self.offline = self._kwarg(kwargs, 'offline', False) + self.scope = self._kwarg(kwargs, "scope", []) + self.offline = self._kwarg(kwargs, "offline", False) # ======================================================================== # Internal methods @@ -130,13 +129,23 @@ class OAuth2(providers.AuthorizationProvider): # pylint:disable=no-self-use # Most providers accept csv scope. - return ','.join(scope) if scope else '' + return ",".join(scope) if scope else "" @classmethod def create_request_elements( - cls, request_type, credentials, url, method='GET', params=None, - headers=None, body='', secret=None, redirect_uri='', scope='', - csrf='', user_state='' + cls, + request_type, + credentials, + url, + method="GET", + params=None, + headers=None, + body="", + secret=None, + redirect_uri="", + scope="", + csrf="", + user_state="", ): """ Creates |oauth2| request elements. @@ -145,10 +154,10 @@ class OAuth2(providers.AuthorizationProvider): headers = headers or {} params = params or {} - consumer_key = credentials.consumer_key or '' - consumer_secret = credentials.consumer_secret or '' - token = credentials.token or '' - refresh_token = credentials.refresh_token or credentials.token or '' + consumer_key = credentials.consumer_key or "" + consumer_secret = credentials.consumer_secret or "" + token = credentials.token or "" + refresh_token = credentials.refresh_token or credentials.token or "" # Separate url base and query parameters. url, base_params = cls._split_url(url) @@ -159,58 +168,58 @@ class OAuth2(providers.AuthorizationProvider): if request_type == cls.USER_AUTHORIZATION_REQUEST_TYPE: # User authorization request. # TODO: Raise error for specific message for each missing argument. - if consumer_key and redirect_uri and ( - csrf or not cls.supports_csrf_protection): - params['client_id'] = consumer_key - params['redirect_uri'] = redirect_uri - params['scope'] = scope + if consumer_key and redirect_uri and (csrf or not cls.supports_csrf_protection): + params["client_id"] = consumer_key + params["redirect_uri"] = redirect_uri + params["scope"] = scope if cls.supports_user_state: - params['state'] = base64.urlsafe_b64encode( - json.dumps( - {"csrf": csrf, "user_state": user_state} - ).encode('utf-8') + params["state"] = base64.urlsafe_b64encode( + json.dumps({"csrf": csrf, "user_state": user_state}).encode("utf-8") ) else: - params['state'] = csrf - params['response_type'] = 'code' + params["state"] = csrf + params["response_type"] = "code" # Add authorization header headers.update(cls._authorization_header(credentials)) else: raise OAuth2Error( - 'Credentials with valid consumer_key and arguments ' - 'redirect_uri, scope and state are required to create ' - 'OAuth 2.0 user authorization request elements!') + "Credentials with valid consumer_key and arguments " + "redirect_uri, scope and state are required to create " + "OAuth 2.0 user authorization request elements!" + ) elif request_type == cls.ACCESS_TOKEN_REQUEST_TYPE: # Access token request. if consumer_key and consumer_secret: - params['code'] = token - params['client_id'] = consumer_key - params['client_secret'] = consumer_secret - params['redirect_uri'] = redirect_uri - params['grant_type'] = 'authorization_code' + params["code"] = token + params["client_id"] = consumer_key + params["client_secret"] = consumer_secret + params["redirect_uri"] = redirect_uri + params["grant_type"] = "authorization_code" # TODO: Check whether all providers accept it headers.update(cls._authorization_header(credentials)) else: raise OAuth2Error( - 'Credentials with valid token, consumer_key, ' - 'consumer_secret and argument redirect_uri are required ' - 'to create OAuth 2.0 access token request elements!') + "Credentials with valid token, consumer_key, " + "consumer_secret and argument redirect_uri are required " + "to create OAuth 2.0 access token request elements!" + ) elif request_type == cls.REFRESH_TOKEN_REQUEST_TYPE: # Refresh access token request. if refresh_token and consumer_key and consumer_secret: - params['refresh_token'] = refresh_token - params['client_id'] = consumer_key - params['client_secret'] = consumer_secret - params['grant_type'] = 'refresh_token' + params["refresh_token"] = refresh_token + params["client_id"] = consumer_key + params["client_secret"] = consumer_secret + params["grant_type"] = "refresh_token" else: raise OAuth2Error( - 'Credentials with valid refresh_token, consumer_key, ' - 'consumer_secret are required to create OAuth 2.0 ' - 'refresh token request elements!') + "Credentials with valid refresh_token, consumer_key, " + "consumer_secret are required to create OAuth 2.0 " + "refresh token request elements!" + ) elif request_type == cls.PROTECTED_RESOURCE_REQUEST_TYPE: # Protected resource request. @@ -219,21 +228,19 @@ class OAuth2(providers.AuthorizationProvider): # http://tools.ietf.org/html/rfc6749#section-7.1 if credentials.token_type == cls.BEARER: # http://tools.ietf.org/html/rfc6750#section-2.1 - headers.update( - {'Authorization': 'Bearer {0}'.format(credentials.token)}) + headers.update({"Authorization": "Bearer {0}".format(credentials.token)}) elif token: - params['access_token'] = token + params["access_token"] = token else: raise OAuth2Error( - 'Credentials with valid token are required to create ' - 'OAuth 2.0 protected resources request elements!') + "Credentials with valid token are required to create " + "OAuth 2.0 protected resources request elements!" + ) - request_elements = core.RequestElements( - url, method, params, headers, body) + request_elements = core.RequestElements(url, method, params, headers, body) - return cls._x_request_elements_filter( - request_type, request_elements, credentials) + return cls._x_request_elements_filter(request_type, request_elements, credentials) @staticmethod def _x_refresh_credentials_if(credentials): @@ -262,14 +269,15 @@ class OAuth2(providers.AuthorizationProvider): @classmethod def to_tuple(cls, credentials): - return (credentials.token, - credentials.refresh_token, - credentials.expiration_time, - cls.TOKEN_TYPES.index(credentials.token_type)) + return ( + credentials.token, + credentials.refresh_token, + credentials.expiration_time, + cls.TOKEN_TYPES.index(credentials.token_type), + ) @classmethod def reconstruct(cls, deserialized_tuple, credentials, cfg): - token, refresh_token, expiration_time, token_type = deserialized_tuple credentials.token = token @@ -280,7 +288,7 @@ class OAuth2(providers.AuthorizationProvider): return credentials @classmethod - def decode_state(cls, state, param='user_state'): + def decode_state(cls, state, param="user_state"): """ Decode state and return param. @@ -299,10 +307,9 @@ class OAuth2(providers.AuthorizationProvider): # urlsafe_b64 may include = which the browser quotes so must # unquote Cast to str to void b64decode translation error. Base64 # should be str compatible. - return json.loads(base64.urlsafe_b64decode( - unquote(str(state))).decode('utf-8'))[param] + return json.loads(base64.urlsafe_b64decode(unquote(str(state))).decode("utf-8"))[param] else: - return state if param == 'csrf' else '' + return state if param == "csrf" else "" def refresh_credentials(self, credentials): """ @@ -321,17 +328,17 @@ class OAuth2(providers.AuthorizationProvider): # We need consumer key and secret to make this kind of request. cfg = credentials.config.get(credentials.provider_name) - credentials.consumer_key = cfg.get('consumer_key') - credentials.consumer_secret = cfg.get('consumer_secret') + credentials.consumer_key = cfg.get("consumer_key") + credentials.consumer_secret = cfg.get("consumer_secret") request_elements = self.create_request_elements( request_type=self.REFRESH_TOKEN_REQUEST_TYPE, credentials=credentials, url=self.access_token_url, - method='POST' + method="POST", ) - self._log(logging.INFO, u'Refreshing credentials.') + self._log(logging.INFO, "Refreshing credentials.") response = self._fetch(*request_elements) # We no longer need consumer info. @@ -339,68 +346,59 @@ class OAuth2(providers.AuthorizationProvider): credentials.consumer_secret = None # Extract the refreshed data. - access_token = response.data.get('access_token') - refresh_token = response.data.get('refresh_token') + access_token = response.data.get("access_token") + refresh_token = response.data.get("refresh_token") # Update credentials only if there is access token. if access_token: credentials.token = access_token - credentials.expire_in = response.data.get('expires_in') + credentials.expire_in = response.data.get("expires_in") # Update refresh token only if there is a new one. if refresh_token: credentials.refresh_token = refresh_token # Handle different naming conventions across providers. - credentials = self._x_credentials_parser( - credentials, response.data) + credentials = self._x_credentials_parser(credentials, response.data) return response @providers.login_decorator def login(self): - # get request parameters from which we can determine the login phase - authorization_code = self.params.get('code') - error = self.params.get('error') - error_message = self.params.get('error_message') - state = self.params.get('state') + authorization_code = self.params.get("code") + error = self.params.get("error") + error_message = self.params.get("error_message") + state = self.params.get("state") # optional user_state to be passed in oauth2 state - user_state = self.params.get('user_state', '') + user_state = self.params.get("user_state", "") if authorization_code or not self.user_authorization_url: - if authorization_code: # ============================================================= # Phase 2 after redirect with success # ============================================================= - self._log( - logging.INFO, - u'Continuing OAuth 2.0 authorization procedure after ' - u'redirect.') + self._log(logging.INFO, "Continuing OAuth 2.0 authorization procedure after redirect.") # validate CSRF token if self.supports_csrf_protection: - self._log( - logging.INFO, - u'Validating request by comparing request state with ' - u'stored state.') - stored_csrf = self._session_get('csrf') + self._log(logging.INFO, "Validating request by comparing request state with stored state.") + stored_csrf = self._session_get("csrf") - state_csrf = self.decode_state(state, 'csrf') + state_csrf = self.decode_state(state, "csrf") if not stored_csrf: - raise FailureError(u'Unable to retrieve stored state!') + raise FailureError("Unable to retrieve stored state!") elif stored_csrf != state_csrf: raise FailureError( - u'The returned state csrf cookie "{0}" doesn\'t ' - u'match with the stored state!'.format( + 'The returned state csrf cookie "{0}" doesn\'t match with the stored state!'.format( state_csrf ), - url=self.user_authorization_url) - self._log(logging.INFO, u'Request is valid.') + url=self.user_authorization_url, + ) + self._log(logging.INFO, "Request is valid.") else: - self._log(logging.WARN, u'Skipping CSRF validation!') + self._log(logging.WARN, "Skipping CSRF validation!") elif not self.user_authorization_url: # ============================================================= @@ -408,15 +406,11 @@ class OAuth2(providers.AuthorizationProvider): # ============================================================= self._log( - logging.INFO, - u'Starting OAuth 2.0 authorization procedure without ' - u'user authorization redirect.') + logging.INFO, "Starting OAuth 2.0 authorization procedure without user authorization redirect." + ) # exchange authorization code for access token by the provider - self._log( - logging.INFO, - u'Fetching access token from {0}.'.format( - self.access_token_url)) + self._log(logging.INFO, "Fetching access token from {0}.".format(self.access_token_url)) self.credentials.token = authorization_code @@ -427,45 +421,42 @@ class OAuth2(providers.AuthorizationProvider): method=self.token_request_method, redirect_uri=self.url, params=self.access_token_params, - headers=self.access_token_headers + headers=self.access_token_headers, ) response = self._fetch(*request_elements) self.access_token_response = response - access_token = response.data.get('access_token', '') - refresh_token = response.data.get('refresh_token', '') + access_token = response.data.get("access_token", "") + refresh_token = response.data.get("refresh_token", "") if response.status != 200 or not access_token: raise FailureError( - 'Failed to obtain OAuth 2.0 access token from {0}! ' - 'HTTP status: {1}, message: {2}.'.format( - self.access_token_url, - response.status, - response.content + "Failed to obtain OAuth 2.0 access token from {0}! HTTP status: {1}, message: {2}.".format( + self.access_token_url, response.status, response.content ), original_message=response.content, status=response.status, - url=self.access_token_url) + url=self.access_token_url, + ) - self._log(logging.INFO, u'Got access token.') + self._log(logging.INFO, "Got access token.") if refresh_token: - self._log(logging.INFO, u'Got refresh access token.') + self._log(logging.INFO, "Got refresh access token.") # OAuth 2.0 credentials need access_token, refresh_token, # token_type and expire_in. self.credentials.token = access_token self.credentials.refresh_token = refresh_token - self.credentials.expire_in = response.data.get('expires_in') - self.credentials.token_type = response.data.get('token_type', '') + self.credentials.expire_in = response.data.get("expires_in") + self.credentials.token_type = response.data.get("token_type", "") # sWe don't need these two guys anymore. - self.credentials.consumer_key = '' - self.credentials.consumer_secret = '' + self.credentials.consumer_key = "" + self.credentials.consumer_secret = "" # update credentials - self.credentials = self._x_credentials_parser( - self.credentials, response.data) + self.credentials = self._x_credentials_parser(self.credentials, response.data) # create user self._update_or_create_user(response.data, self.credentials) @@ -479,58 +470,42 @@ class OAuth2(providers.AuthorizationProvider): # Phase 2 after redirect with error # ================================================================= - error_reason = self.params.get('error_reason') or error - error_description = self.params.get('error_description') \ - or error_message or error + error_reason = self.params.get("error_reason") or error + error_description = self.params.get("error_description") or error_message or error - if error_reason and 'denied' in error_reason: - raise CancellationError(error_description, - url=self.user_authorization_url) + if error_reason and "denied" in error_reason: + raise CancellationError(error_description, url=self.user_authorization_url) else: - raise FailureError( - error_description, - url=self.user_authorization_url) + raise FailureError(error_description, url=self.user_authorization_url) - elif ( - not self.params - or len(self.params) == 1 - and 'user_state' in self.params - ): + elif not self.params or len(self.params) == 1 and "user_state" in self.params: # ================================================================= # Phase 1 before redirect # ================================================================= - self._log( - logging.INFO, - u'Starting OAuth 2.0 authorization procedure.') + self._log(logging.INFO, "Starting OAuth 2.0 authorization procedure.") - csrf = '' + csrf = "" if self.supports_csrf_protection: # generate csfr csrf = self.csrf_generator(self.settings.secret) # and store it to session - self._session_set('csrf', csrf) + self._session_set("csrf", csrf) else: - self._log( - logging.WARN, - u'Provider doesn\'t support CSRF validation!') + self._log(logging.WARN, "Provider doesn't support CSRF validation!") request_elements = self.create_request_elements( request_type=self.USER_AUTHORIZATION_REQUEST_TYPE, credentials=self.credentials, url=self.user_authorization_url, redirect_uri=self.url, - scope=self._x_scope_parser( - self.scope), + scope=self._x_scope_parser(self.scope), csrf=csrf, user_state=user_state, - params=self.user_authorization_params + params=self.user_authorization_params, ) - self._log( - logging.INFO, - u'Redirecting user to {0}.'.format( - request_elements.full_url)) + self._log(logging.INFO, "Redirecting user to {0}.".format(request_elements.full_url)) self.redirect(request_elements.full_url) @@ -576,30 +551,25 @@ class Amazon(OAuth2): """ - user_authorization_url = 'https://www.amazon.com/ap/oa' - access_token_url = 'https://api.amazon.com/auth/o2/token' - user_info_url = 'https://api.amazon.com/user/profile' - user_info_scope = ['profile', 'postal_code'] + user_authorization_url = "https://www.amazon.com/ap/oa" + access_token_url = "https://api.amazon.com/auth/o2/token" + user_info_url = "https://api.amazon.com/user/profile" + user_info_scope = ["profile", "postal_code"] - supported_user_attributes = core.SupportedUserAttributes( - email=True, - id=True, - name=True, - postal_code=True - ) + supported_user_attributes = core.SupportedUserAttributes(email=True, id=True, name=True, postal_code=True) def _x_scope_parser(self, scope): # Amazon has space-separated scopes - return ' '.join(scope) + return " ".join(scope) @staticmethod def _x_user_parser(user, data): - user.id = data.get('user_id') + user.id = data.get("user_id") return user @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @@ -619,32 +589,31 @@ class Behance(OAuth2): """ - user_authorization_url = 'https://www.behance.net/v2/oauth/authenticate' - access_token_url = 'https://www.behance.net/v2/oauth/token' - user_info_url = '' + user_authorization_url = "https://www.behance.net/v2/oauth/authenticate" + access_token_url = "https://www.behance.net/v2/oauth/token" + user_info_url = "" - user_info_scope = ['activity_read'] + user_info_scope = ["activity_read"] def _x_scope_parser(self, scope): """ Behance has pipe-separated scopes. """ - return '|'.join(scope) + return "|".join(scope) @staticmethod def _x_user_parser(user, data): + _user = data.get("user", {}) - _user = data.get('user', {}) - - user.id = _user.get('id') - user.first_name = _user.get('first_name') - user.last_name = _user.get('last_name') - user.username = _user.get('username') - user.city = _user.get('city') - user.country = _user.get('country') - user.link = _user.get('url') - user.name = _user.get('display_name') - user.picture = _user.get('images', {}).get('138') + user.id = _user.get("id") + user.first_name = _user.get("first_name") + user.last_name = _user.get("last_name") + user.username = _user.get("username") + user.city = _user.get("city") + user.country = _user.get("country") + user.link = _user.get("url") + user.name = _user.get("display_name") + user.picture = _user.get("images", {}).get("138") return user @@ -686,37 +655,31 @@ class Bitly(OAuth2): """ - supported_user_attributes = core.SupportedUserAttributes( - id=True, - link=True, - name=True, - picture=True, - username=True - ) + supported_user_attributes = core.SupportedUserAttributes(id=True, link=True, name=True, picture=True, username=True) supports_csrf_protection = False _x_use_authorization_header = False - user_authorization_url = 'https://bitly.com/oauth/authorize' - access_token_url = 'https://api-ssl.bitly.com/oauth/access_token' - user_info_url = 'https://api-ssl.bitly.com/v3/user/info' + user_authorization_url = "https://bitly.com/oauth/authorize" + access_token_url = "https://api-ssl.bitly.com/oauth/access_token" + user_info_url = "https://api-ssl.bitly.com/v3/user/info" def __init__(self, *args, **kwargs): super(Bitly, self).__init__(*args, **kwargs) if self.offline: - if 'grant_type' not in self.access_token_params: - self.access_token_params['grant_type'] = 'refresh_token' + if "grant_type" not in self.access_token_params: + self.access_token_params["grant_type"] = "refresh_token" @staticmethod def _x_user_parser(user, data): - info = data.get('data', {}) + info = data.get("data", {}) - user.id = info.get('login') - user.name = info.get('full_name') - user.username = info.get('display_name') - user.picture = info.get('profile_image') - user.link = info.get('profile_url') + user.id = info.get("login") + user.name = info.get("full_name") + user.username = info.get("display_name") + user.picture = info.get("profile_image") + user.link = info.get("profile_url") return user @@ -735,13 +698,13 @@ class Cosm(OAuth2): """ - user_authorization_url = 'https://cosm.com/oauth/authenticate' - access_token_url = 'https://cosm.com/oauth/token' - user_info_url = '' + user_authorization_url = "https://cosm.com/oauth/authenticate" + access_token_url = "https://cosm.com/oauth/token" + user_info_url = "" @staticmethod def _x_user_parser(user, data): - user.id = user.username = data.get('user') + user.id = user.username = data.get("user") return user @@ -797,28 +760,24 @@ class DeviantART(OAuth2): """ - user_authorization_url = 'https://www.deviantart.com/oauth2/authorize' - access_token_url = 'https://www.deviantart.com/oauth2/token' - user_info_url = 'https://www.deviantart.com/api/oauth2/user/whoami' + user_authorization_url = "https://www.deviantart.com/oauth2/authorize" + access_token_url = "https://www.deviantart.com/oauth2/token" + user_info_url = "https://www.deviantart.com/api/oauth2/user/whoami" - user_info_scope = ['basic'] + user_info_scope = ["basic"] - supported_user_attributes = core.SupportedUserAttributes( - name=True, - picture=True, - username=True - ) + supported_user_attributes = core.SupportedUserAttributes(name=True, picture=True, username=True) def __init__(self, *args, **kwargs): super(DeviantART, self).__init__(*args, **kwargs) if self.offline: - if 'grant_type' not in self.access_token_params: - self.access_token_params['grant_type'] = 'refresh_token' + if "grant_type" not in self.access_token_params: + self.access_token_params["grant_type"] = "refresh_token" @staticmethod def _x_user_parser(user, data): - user.picture = data.get('usericonurl') + user.picture = data.get("usericonurl") return user @@ -857,9 +816,9 @@ class Eventbrite(OAuth2): """ - user_authorization_url = 'https://www.eventbrite.com/oauth/authorize' - access_token_url = 'https://www.eventbrite.com/oauth/token' - user_info_url = 'https://www.eventbriteapi.com/v3/users/me' + user_authorization_url = "https://www.eventbrite.com/oauth/authorize" + access_token_url = "https://www.eventbrite.com/oauth/token" + user_info_url = "https://www.eventbriteapi.com/v3/users/me" supported_user_attributes = core.SupportedUserAttributes( email=True, @@ -871,15 +830,15 @@ class Eventbrite(OAuth2): @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @staticmethod def _x_user_parser(user, data): - for email in data.get('emails', []): - if email.get('primary'): - user.email = email.get('email') + for email in data.get("emails", []): + if email.get("primary"): + user.email = email.get("email") break return user @@ -912,11 +871,11 @@ class Facebook(OAuth2): * username """ - user_authorization_url = 'https://www.facebook.com/dialog/oauth' - access_token_url = 'https://graph.facebook.com/oauth/access_token' - user_info_url = 'https://graph.facebook.com/v2.3/me' - user_info_scope = ['email', 'public_profile', 'user_birthday', - 'user_location'] + + user_authorization_url = "https://www.facebook.com/dialog/oauth" + access_token_url = "https://graph.facebook.com/oauth/access_token" + user_info_url = "https://graph.facebook.com/v2.3/me" + user_info_scope = ["email", "public_profile", "user_birthday", "user_location"] same_origin = False supported_user_attributes = core.SupportedUserAttributes( @@ -938,16 +897,13 @@ class Facebook(OAuth2): ) @classmethod - def _x_request_elements_filter(cls, request_type, request_elements, - credentials): - + def _x_request_elements_filter(cls, request_type, request_elements, credentials): if request_type == cls.REFRESH_TOKEN_REQUEST_TYPE: # As always, Facebook has it's original name for "refresh_token"! url, method, params, headers, body = request_elements - params['fb_exchange_token'] = params.pop('refresh_token') - params['grant_type'] = 'fb_exchange_token' - request_elements = core.RequestElements(url, method, params, - headers, body) + params["fb_exchange_token"] = params.pop("refresh_token") + params["grant_type"] = "fb_exchange_token" + request_elements = core.RequestElements(url, method, params, headers, body) return request_elements @@ -958,28 +914,26 @@ class Facebook(OAuth2): # to refresh the access token. if self.offline: # Facebook needs an offline_access scope. - if 'offline_access' not in self.scope: - self.scope.append('offline_access') + if "offline_access" not in self.scope: + self.scope.append("offline_access") if self.popup: - self.user_authorization_url += '?display=popup' + self.user_authorization_url += "?display=popup" @staticmethod def _x_user_parser(user, data): - _birth_date = data.get('birthday') + _birth_date = data.get("birthday") if _birth_date: try: - user.birth_date = datetime.datetime.strptime(_birth_date, - '%m/%d/%Y') + user.birth_date = datetime.datetime.strptime(_birth_date, "%m/%d/%Y") except ValueError: pass - user.picture = ('http://graph.facebook.com/{0}/picture?type=large' - .format(user.id)) + user.picture = "http://graph.facebook.com/{0}/picture?type=large".format(user.id) - user.location = data.get('location', {}).get('name') + user.location = data.get("location", {}).get("name") if user.location: - split_location = user.location.split(', ') + split_location = user.location.split(", ") user.city = split_location[0].strip() if len(split_location) > 1: user.country = split_location[1].strip() @@ -993,11 +947,11 @@ class Facebook(OAuth2): """ # Facebook returns "expires" instead of "expires_in". - credentials.expire_in = data.get('expires') + credentials.expire_in = data.get("expires") - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": # TODO: cls is not available here, hardcode for now. - credentials.token_type = 'Bearer' + credentials.token_type = "Bearer" return credentials @@ -1009,8 +963,7 @@ class Facebook(OAuth2): def access(self, url, params=None, **kwargs): if params is None: params = {} - params['fields'] = 'id,first_name,last_name,picture,email,gender,' + \ - 'timezone,location,birthday,locale' + params["fields"] = "id,first_name,last_name,picture,email,gender," + "timezone,location,birthday,locale" return super(Facebook, self).access(url, params, **kwargs) @@ -1056,9 +1009,9 @@ class Foursquare(OAuth2): """ - user_authorization_url = 'https://foursquare.com/oauth2/authenticate' - access_token_url = 'https://foursquare.com/oauth2/access_token' - user_info_url = 'https://api.foursquare.com/v2/users/self' + user_authorization_url = "https://foursquare.com/oauth2/authenticate" + access_token_url = "https://foursquare.com/oauth2/access_token" + user_info_url = "https://api.foursquare.com/v2/users/self" same_origin = False @@ -1074,99 +1027,87 @@ class Foursquare(OAuth2): location=True, name=True, phone=True, - picture=True + picture=True, ) @classmethod - def _x_request_elements_filter(cls, request_type, request_elements, - credentials): - + def _x_request_elements_filter(cls, request_type, request_elements, credentials): if request_type == cls.PROTECTED_RESOURCE_REQUEST_TYPE: # Foursquare uses OAuth 1.0 "oauth_token" for what should be # "access_token" in OAuth 2.0! url, method, params, headers, body = request_elements - params['oauth_token'] = params.pop('access_token') + params["oauth_token"] = params.pop("access_token") # Foursquare needs the version "v" parameter in every request. # https://developer.foursquare.com/overview/versioning - if not params.get('v'): - params['v'] = '20140501' + if not params.get("v"): + params["v"] = "20140501" - request_elements = core.RequestElements(url, method, params, - headers, body) + request_elements = core.RequestElements(url, method, params, headers, body) return request_elements @staticmethod def _x_user_parser(user, data): + _resp = data.get("response", {}) + _user = _resp.get("user", {}) - _resp = data.get('response', {}) - _user = _resp.get('user', {}) + user.id = _user.get("id") + user.first_name = _user.get("firstName") + user.last_name = _user.get("lastName") + user.gender = _user.get("gender") - user.id = _user.get('id') - user.first_name = _user.get('firstName') - user.last_name = _user.get('lastName') - user.gender = _user.get('gender') - - _birth_date = _user.get('birthday') + _birth_date = _user.get("birthday") if _birth_date: user.birth_date = datetime.datetime.fromtimestamp(_birth_date) - _photo = _user.get('photo', {}) + _photo = _user.get("photo", {}) if isinstance(_photo, dict): - _photo_prefix = _photo.get('prefix', '').strip('/') - _photo_suffix = _photo.get('suffix', '').strip('/') - user.picture = '/'.join([_photo_prefix, _photo_suffix]) + _photo_prefix = _photo.get("prefix", "").strip("/") + _photo_suffix = _photo.get("suffix", "").strip("/") + user.picture = "/".join([_photo_prefix, _photo_suffix]) if isinstance(_photo, str): user.picture = _photo - user.location = _user.get('homeCity') + user.location = _user.get("homeCity") if user.location: - split_location = user.location.split(',') + split_location = user.location.split(",") user.city = split_location[0].strip() if len(user.location) > 1: user.country = split_location[1].strip() - _contact = _user.get('contact', {}) - user.email = _contact.get('email') - user.phone = _contact.get('phone') + _contact = _user.get("contact", {}) + user.email = _contact.get("email") + user.phone = _contact.get("phone") return user class Bitbucket(OAuth2): - - user_authorization_url = 'https://bitbucket.org/site/oauth2/authorize' - access_token_url = 'https://bitbucket.org/site/oauth2/access_token' - user_info_url = 'https://bitbucket.org/api/2.0/user' - user_email_info_url = 'https://bitbucket.org/api/2.0/user/emails' + user_authorization_url = "https://bitbucket.org/site/oauth2/authorize" + access_token_url = "https://bitbucket.org/site/oauth2/access_token" + user_info_url = "https://bitbucket.org/api/2.0/user" + user_email_info_url = "https://bitbucket.org/api/2.0/user/emails" same_origin = False supported_user_attributes = core.SupportedUserAttributes( - id=True, - first_name=True, - last_name=True, - link=True, - name=True, - picture=True, - username=True, - email=True + id=True, first_name=True, last_name=True, link=True, name=True, picture=True, username=True, email=True ) @staticmethod def _x_user_parser(user, data): - user.username = user.id = data.get('username') - user.name = data.get('display_name') - user.first_name = data.get('first_name') - user.last_name = data.get('last_name') + user.username = user.id = data.get("username") + user.name = data.get("display_name") + user.first_name = data.get("first_name") + user.last_name = data.get("last_name") return user @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @@ -1179,7 +1120,7 @@ class Bitbucket(OAuth2): response.data.setdefault("email", None) email_response = self.access(self.user_email_info_url) - emails = email_response.data.get('values', []) + emails = email_response.data.get("values", []) if emails: for item in emails: if item.get("is_primary", False): @@ -1246,32 +1187,26 @@ class GitHub(OAuth2): """ - user_authorization_url = 'https://github.com/login/oauth/authorize' - access_token_url = 'https://github.com/login/oauth/access_token' - user_info_url = 'https://api.github.com/user' + user_authorization_url = "https://github.com/login/oauth/authorize" + access_token_url = "https://github.com/login/oauth/access_token" + user_info_url = "https://api.github.com/user" same_origin = False supported_user_attributes = core.SupportedUserAttributes( - email=True, - id=True, - link=True, - location=True, - name=True, - picture=True, - username=True + email=True, id=True, link=True, location=True, name=True, picture=True, username=True ) @staticmethod def _x_user_parser(user, data): - user.username = data.get('login') - user.picture = data.get('avatar_url') - user.link = data.get('html_url') + user.username = data.get("login") + user.picture = data.get("avatar_url") + user.link = data.get("html_url") return user @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @@ -1348,21 +1283,14 @@ class Google(OAuth2): """ - user_authorization_url = 'https://accounts.google.com/o/oauth2/auth' - access_token_url = 'https://accounts.google.com/o/oauth2/token' - user_info_url = 'https://www.googleapis.com/oauth2/v3/userinfo?alt=json' + user_authorization_url = "https://accounts.google.com/o/oauth2/auth" + access_token_url = "https://accounts.google.com/o/oauth2/token" + user_info_url = "https://www.googleapis.com/oauth2/v3/userinfo?alt=json" - user_info_scope = ['profile', - 'email'] + user_info_scope = ["profile", "email"] supported_user_attributes = core.SupportedUserAttributes( - id=True, - email=True, - name=True, - first_name=True, - last_name=True, - locale=True, - picture=True + id=True, email=True, name=True, first_name=True, last_name=True, locale=True, picture=True ) def __init__(self, *args, **kwargs): @@ -1371,17 +1299,16 @@ class Google(OAuth2): # Handle special Google requirements to be able to refresh the access # token. if self.offline: - if 'access_type' not in self.user_authorization_params: + if "access_type" not in self.user_authorization_params: # Google needs access_type=offline param in the user # authorization request. - self.user_authorization_params['access_type'] = 'offline' - if 'approval_prompt' not in self.user_authorization_params: + self.user_authorization_params["access_type"] = "offline" + if "approval_prompt" not in self.user_authorization_params: # And also approval_prompt=force. - self.user_authorization_params['approval_prompt'] = 'force' + self.user_authorization_params["approval_prompt"] = "force" @classmethod - def _x_request_elements_filter(cls, request_type, request_elements, - credentials): + def _x_request_elements_filter(cls, request_type, request_elements, credentials): """ Google doesn't accept client ID and secret to be at the same time in request parameters and in the basic authorization header in the access @@ -1389,26 +1316,26 @@ class Google(OAuth2): """ if request_type is cls.ACCESS_TOKEN_REQUEST_TYPE: params = request_elements[2] - del params['client_id'] - del params['client_secret'] + del params["client_id"] + del params["client_secret"] return request_elements @staticmethod def _x_user_parser(user, data): - emails = data.get('emails', []) + emails = data.get("emails", []) if emails: - user.email = emails[0].get('value') + user.email = emails[0].get("value") for email in emails: - if email.get('type') == 'account': - user.email = email.get('value') + if email.get("type") == "account": + user.email = email.get("value") break - user.id = data.get('sub') - user.name = data.get('name') - user.first_name = data.get('given_name', '') - user.last_name = data.get('family_name', '') - user.locale = data.get('locale', '') - user.picture = data.get('picture', '') + user.id = data.get("sub") + user.name = data.get("name") + user.first_name = data.get("given_name", "") + user.last_name = data.get("family_name", "") + user.locale = data.get("locale", "") + user.picture = data.get("picture", "") user.email_verified = data.get("email_verified") user.hosted_domain = data.get("hd") @@ -1418,7 +1345,7 @@ class Google(OAuth2): """ Google has space-separated scopes. """ - return ' '.join(scope) + return " ".join(scope) class LinkedIn(OAuth2): @@ -1459,17 +1386,18 @@ class LinkedIn(OAuth2): """ - user_authorization_url = 'https://www.linkedin.com/uas/oauth2/' + \ - 'authorization' - access_token_url = 'https://www.linkedin.com/uas/oauth2/accessToken' - user_info_url = ('https://api.linkedin.com/v1/people/~:' - '(id,first-name,last-name,formatted-name,location,' - 'picture-url,public-profile-url,email-address)' - '?format=json') + user_authorization_url = "https://www.linkedin.com/uas/oauth2/" + "authorization" + access_token_url = "https://www.linkedin.com/uas/oauth2/accessToken" + user_info_url = ( + "https://api.linkedin.com/v1/people/~:" + "(id,first-name,last-name,formatted-name,location," + "picture-url,public-profile-url,email-address)" + "?format=json" + ) - user_info_scope = ['r_emailaddress'] + user_info_scope = ["r_emailaddress"] - token_request_method = 'GET' # To avoid a bug with OAuth2.0 on Linkedin + token_request_method = "GET" # To avoid a bug with OAuth2.0 on Linkedin # http://developer.linkedin.com/forum/unauthorized-invalid-or-expired-token-immediately-after-receiving-oauth2-token supported_user_attributes = core.SupportedUserAttributes( @@ -1482,40 +1410,36 @@ class LinkedIn(OAuth2): link=True, location=False, name=True, - picture=True + picture=True, ) @classmethod - def _x_request_elements_filter(cls, request_type, request_elements, - credentials): + def _x_request_elements_filter(cls, request_type, request_elements, credentials): if request_type == cls.PROTECTED_RESOURCE_REQUEST_TYPE: # LinkedIn too has it's own terminology! url, method, params, headers, body = request_elements - params['oauth2_access_token'] = params.pop('access_token') - request_elements = core.RequestElements(url, method, params, - headers, body) + params["oauth2_access_token"] = params.pop("access_token") + request_elements = core.RequestElements(url, method, params, headers, body) return request_elements @staticmethod def _x_user_parser(user, data): + user.first_name = data.get("firstName") + user.last_name = data.get("lastName") + user.email = data.get("emailAddress") + user.name = data.get("formattedName") + user.city = user.city = data.get("location", {}).get("name") + user.country = data.get("location", {}).get("country", {}).get("code") + user.phone = data.get("phoneNumbers", {}).get("values", [{}])[0].get("phoneNumber") + user.picture = data.get("pictureUrl") + user.link = data.get("publicProfileUrl") - user.first_name = data.get('firstName') - user.last_name = data.get('lastName') - user.email = data.get('emailAddress') - user.name = data.get('formattedName') - user.city = user.city = data.get('location', {}).get('name') - user.country = data.get('location', {}).get('country', {}).get('code') - user.phone = data.get('phoneNumbers', {}).get('values', [{}])[0]\ - .get('phoneNumber') - user.picture = data.get('pictureUrl') - user.link = data.get('publicProfileUrl') - - _birthdate = data.get('dateOfBirth', {}) + _birthdate = data.get("dateOfBirth", {}) if _birthdate: - _day = _birthdate.get('day') - _month = _birthdate.get('month') - _year = _birthdate.get('year') + _day = _birthdate.get("day") + _month = _birthdate.get("month") + _year = _birthdate.get("year") if _day and _month and _year: user.birth_date = datetime.datetime(_year, _month, _day) @@ -1552,11 +1476,11 @@ class MicrosoftOnline(OAuth2): """ - user_authorization_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize' - access_token_url = 'https://login.microsoftonline.com/common/oauth2/v2.0/token' + user_authorization_url = "https://login.microsoftonline.com/common/oauth2/v2.0/authorize" + access_token_url = "https://login.microsoftonline.com/common/oauth2/v2.0/token" user_info_url = "https://graph.microsoft.com/v1.0/me" - user_info_scope = ['openid profile'] + user_info_scope = ["openid profile"] supported_user_attributes = core.SupportedUserAttributes( id=True, @@ -1573,29 +1497,29 @@ class MicrosoftOnline(OAuth2): def __init__(self, *args, **kwargs): super(MicrosoftOnline, self).__init__(*args, **kwargs) auth = args[0] - provider_name = kwargs.get('provider_name') - domain = auth.config.get(provider_name, {}).get('domain') + provider_name = kwargs.get("provider_name") + domain = auth.config.get(provider_name, {}).get("domain") if domain is not None: - self.user_authorization_url = MicrosoftOnline.user_authorization_url.replace('/common/', '/%s/' % domain) - self.access_token_url = MicrosoftOnline.access_token_url.replace('/common/', '/%s/' % domain) + self.user_authorization_url = MicrosoftOnline.user_authorization_url.replace("/common/", "/%s/" % domain) + self.access_token_url = MicrosoftOnline.access_token_url.replace("/common/", "/%s/" % domain) @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @staticmethod def _x_user_parser(user, data): - user.id = data.get('id') - user.name = data.get('displayName', '') - user.first_name = data.get('givenName', '') - user.last_name = data.get('surname', '') - user.email = data.get('mail', '') - user.location = data.get('officeLocation', '') - user.phone = data.get('mobilePhone', '') - user.picture = data.get('picture', '') - user.username = data.get('userPrincipalName', '') + user.id = data.get("id") + user.name = data.get("displayName", "") + user.first_name = data.get("givenName", "") + user.last_name = data.get("surname", "") + user.email = data.get("mail", "") + user.location = data.get("officeLocation", "") + user.phone = data.get("mobilePhone", "") + user.picture = data.get("picture", "") + user.username = data.get("userPrincipalName", "") return user @@ -1620,20 +1544,17 @@ class PayPal(OAuth2): supported_user_attributes = core.SupportedUserAttributes() @classmethod - def _x_request_elements_filter( - cls, request_type, request_elements, credentials): - + def _x_request_elements_filter(cls, request_type, request_elements, credentials): if request_type == cls.ACCESS_TOKEN_REQUEST_TYPE: url, method, params, headers, body = request_elements - params['grant_type'] = 'client_credentials' - request_elements = core.RequestElements( - url, method, params, headers, body) + params["grant_type"] = "client_credentials" + request_elements = core.RequestElements(url, method, params, headers, body) return request_elements - user_authorization_url = '' - access_token_url = 'https://api.sandbox.paypal.com/v1/oauth2/token' - user_info_url = '' + user_authorization_url = "" + access_token_url = "https://api.sandbox.paypal.com/v1/oauth2/token" + user_info_url = "" class Reddit(OAuth2): @@ -1696,35 +1617,31 @@ class Reddit(OAuth2): """ - user_authorization_url = 'https://ssl.reddit.com/api/v1/authorize' - access_token_url = 'https://ssl.reddit.com/api/v1/access_token' - user_info_url = 'https://oauth.reddit.com/api/v1/me.json' + user_authorization_url = "https://ssl.reddit.com/api/v1/authorize" + access_token_url = "https://ssl.reddit.com/api/v1/access_token" + user_info_url = "https://oauth.reddit.com/api/v1/me.json" - user_info_scope = ['identity'] + user_info_scope = ["identity"] - supported_user_attributes = core.SupportedUserAttributes( - id=True, - name=True, - username=True - ) + supported_user_attributes = core.SupportedUserAttributes(id=True, name=True, username=True) def __init__(self, *args, **kwargs): super(Reddit, self).__init__(*args, **kwargs) if self.offline: - if 'duration' not in self.user_authorization_params: + if "duration" not in self.user_authorization_params: # http://www.reddit.com/r/changelog/comments/11jab9/reddit_change_permanent_oauth_grants_using/ - self.user_authorization_params['duration'] = 'permanent' + self.user_authorization_params["duration"] = "permanent" @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @staticmethod def _x_user_parser(user, data): - user.username = data.get('name') + user.username = data.get("name") return user @@ -1755,14 +1672,13 @@ class Viadeo(OAuth2): """ - user_authorization_url = 'https://secure.viadeo.com/oauth-provider/' + \ - 'authorize2' - access_token_url = 'https://secure.viadeo.com/oauth-provider/access_token2' - user_info_url = 'https://api.viadeo.com/me' + user_authorization_url = "https://secure.viadeo.com/oauth-provider/" + "authorize2" + access_token_url = "https://secure.viadeo.com/oauth-provider/access_token2" + user_info_url = "https://api.viadeo.com/me" @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer_token': + if data.get("token_type") == "bearer_token": credentials.token_type = cls.BEARER return credentials @@ -1773,16 +1689,16 @@ class Viadeo(OAuth2): @staticmethod def _x_user_parser(user, data): - user.username = data.get('nickname') - user.picture = data.get('picture_large') - user.picture = data.get('picture_large') - user.locale = data.get('language') - user.email = data.get('') - user.email = data.get('') - user.country = data.get('location', {}).get('country') - user.city = data.get('location', {}).get('city') - user.postal_code = data.get('location', {}).get('zipcode') - user.timezone = data.get('location', {}).get('timezone') + user.username = data.get("nickname") + user.picture = data.get("picture_large") + user.picture = data.get("picture_large") + user.locale = data.get("language") + user.email = data.get("") + user.email = data.get("") + user.country = data.get("location", {}).get("country") + user.city = data.get("location", {}).get("city") + user.postal_code = data.get("location", {}).get("zipcode") + user.timezone = data.get("location", {}).get("timezone") return user @@ -1842,11 +1758,13 @@ class VK(OAuth2): """ - user_authorization_url = 'http://api.vkontakte.ru/oauth/authorize' - access_token_url = 'https://api.vkontakte.ru/oauth/access_token' - user_info_url = 'https://api.vk.com/method/getProfiles?' + \ - 'fields=uid,first_name,last_name,nickname,sex,bdate,' + \ - 'city,country,timezone,photo_big' + user_authorization_url = "http://api.vkontakte.ru/oauth/authorize" + access_token_url = "https://api.vkontakte.ru/oauth/access_token" + user_info_url = ( + "https://api.vk.com/method/getProfiles?" + + "fields=uid,first_name,last_name,nickname,sex,bdate," + + "city,country,timezone,photo_big" + ) supported_user_attributes = core.SupportedUserAttributes( birth_date=True, @@ -1866,26 +1784,25 @@ class VK(OAuth2): super(VK, self).__init__(*args, **kwargs) if self.offline: - if 'offline' not in self.scope: - self.scope.append('offline') + if "offline" not in self.scope: + self.scope.append("offline") @staticmethod def _x_user_parser(user, data): - _resp = data.get('response', [{}])[0] + _resp = data.get("response", [{}])[0] - _birth_date = _resp.get('bdate') + _birth_date = _resp.get("bdate") if _birth_date: - user.birth_date = datetime.datetime.strptime( - _birth_date, '%d.%m.%Y') - user.id = _resp.get('uid') - user.first_name = _resp.get('first_name') - user.gender = _resp.get('sex') - user.last_name = _resp.get('last_name') - user.nickname = _resp.get('nickname') - user.city = _resp.get('city') - user.country = _resp.get('country') - user.timezone = _resp.get('timezone') - user.picture = _resp.get('photo_big') + user.birth_date = datetime.datetime.strptime(_birth_date, "%d.%m.%Y") + user.id = _resp.get("uid") + user.first_name = _resp.get("first_name") + user.gender = _resp.get("sex") + user.last_name = _resp.get("last_name") + user.nickname = _resp.get("nickname") + user.city = _resp.get("city") + user.country = _resp.get("country") + user.timezone = _resp.get("timezone") + user.picture = _resp.get("photo_big") return user @@ -1924,41 +1841,33 @@ class WindowsLive(OAuth2): """ - user_authorization_url = 'https://login.live.com/oauth20_authorize.srf' - access_token_url = 'https://login.live.com/oauth20_token.srf' - user_info_url = 'https://apis.live.net/v5.0/me' + user_authorization_url = "https://login.live.com/oauth20_authorize.srf" + access_token_url = "https://login.live.com/oauth20_token.srf" + user_info_url = "https://apis.live.net/v5.0/me" - user_info_scope = ['wl.basic', 'wl.emails', 'wl.photos'] + user_info_scope = ["wl.basic", "wl.emails", "wl.photos"] supported_user_attributes = core.SupportedUserAttributes( - email=True, - first_name=True, - id=True, - last_name=True, - link=True, - locale=True, - name=True, - picture=True + email=True, first_name=True, id=True, last_name=True, link=True, locale=True, name=True, picture=True ) def __init__(self, *args, **kwargs): super(WindowsLive, self).__init__(*args, **kwargs) if self.offline: - if 'wl.offline_access' not in self.scope: - self.scope.append('wl.offline_access') + if "wl.offline_access" not in self.scope: + self.scope.append("wl.offline_access") @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @staticmethod def _x_user_parser(user, data): - user.email = data.get('emails', {}).get('preferred') - user.picture = 'https://apis.live.net/v5.0/{0}/picture'.format( - data.get('id')) + user.email = data.get("emails", {}).get("preferred") + user.picture = "https://apis.live.net/v5.0/{0}/picture".format(data.get("id")) return user @@ -1996,9 +1905,9 @@ class Yammer(OAuth2): """ - user_authorization_url = 'https://www.yammer.com/dialog/oauth' - access_token_url = 'https://www.yammer.com/oauth2/access_token.json' - user_info_url = 'https://www.yammer.com/api/v1/users/current.json' + user_authorization_url = "https://www.yammer.com/dialog/oauth" + access_token_url = "https://www.yammer.com/oauth2/access_token.json" + user_info_url = "https://www.yammer.com/api/v1/users/current.json" supported_user_attributes = core.SupportedUserAttributes( birth_date=True, @@ -2015,54 +1924,52 @@ class Yammer(OAuth2): phone=True, picture=True, timezone=True, - username=True + username=True, ) @classmethod def _x_credentials_parser(cls, credentials, data): # import pdb; pdb.set_trace() credentials.token_type = cls.BEARER - _access_token = data.get('access_token', {}) - credentials.token = _access_token.get('token') - _expire_in = _access_token.get('expires_at', 0) + _access_token = data.get("access_token", {}) + credentials.token = _access_token.get("token") + _expire_in = _access_token.get("expires_at", 0) if _expire_in: credentials.expire_in = _expire_in return credentials @staticmethod def _x_user_parser(user, data): - # Yammer provides most of the user info in the access token request, # but provides more on in user info request. - _user = data.get('user', {}) + _user = data.get("user", {}) if not _user: # If there is "user key", it is token request. _user = data - user.username = _user.get('name') - user.name = _user.get('full_name') - user.link = _user.get('web_url') - user.picture = _user.get('mugshot_url') + user.username = _user.get("name") + user.name = _user.get("full_name") + user.link = _user.get("web_url") + user.picture = _user.get("mugshot_url") - user.city, user.country = _user.get('location', ',').split(',') + user.city, user.country = _user.get("location", ",").split(",") user.city = user.city.strip() user.country = user.country.strip() - user.locale = _user.get('web_preferences', {}).get('locale') + user.locale = _user.get("web_preferences", {}).get("locale") # Contact - _contact = _user.get('contact', {}) - user.phone = _contact.get('phone_numbers', [{}])[0].get('number') - _emails = _contact.get('email_addresses', []) + _contact = _user.get("contact", {}) + user.phone = _contact.get("phone_numbers", [{}])[0].get("number") + _emails = _contact.get("email_addresses", []) for email in _emails: - if email.get('type', '') == 'primary': - user.email = email.get('address') + if email.get("type", "") == "primary": + user.email = email.get("address") break try: - user.birth_date = datetime.datetime.strptime( - _user.get('birth_date'), "%B %d") + user.birth_date = datetime.datetime.strptime(_user.get("birth_date"), "%B %d") except ValueError: - user.birth_date = _user.get('birth_date') + user.birth_date = _user.get("birth_date") return user @@ -2101,37 +2008,31 @@ class Yandex(OAuth2): """ - user_authorization_url = 'https://oauth.yandex.com/authorize' - access_token_url = 'https://oauth.yandex.com/token' - user_info_url = 'https://login.yandex.ru/info' + user_authorization_url = "https://oauth.yandex.com/authorize" + access_token_url = "https://oauth.yandex.com/token" + user_info_url = "https://login.yandex.ru/info" - supported_user_attributes = core.SupportedUserAttributes( - id=True, - name=True, - username=True - ) + supported_user_attributes = core.SupportedUserAttributes(id=True, name=True, username=True) @classmethod def _x_credentials_parser(cls, credentials, data): - if data.get('token_type') == 'bearer': + if data.get("token_type") == "bearer": credentials.token_type = cls.BEARER return credentials @staticmethod def _x_user_parser(user, data): - # http://api.yandex.ru/login/doc/dg/reference/response.xml - user.name = data.get('real_name') - user.nickname = data.get('display_name') - user.gender = data.get('Sex') - user.email = data.get('Default_email') - user.username = data.get('login') + user.name = data.get("real_name") + user.nickname = data.get("display_name") + user.gender = data.get("Sex") + user.email = data.get("Default_email") + user.username = data.get("login") try: - user.birth_date = datetime.datetime.strptime( - data.get('birthday'), "%Y-%m-%d") + user.birth_date = datetime.datetime.strptime(data.get("birthday"), "%Y-%m-%d") except ValueError: - user.birth_date = data.get('birthday') + user.birth_date = data.get("birthday") return user diff --git a/rhodecode/lib/_vendor/authomatic/providers/openid.py b/rhodecode/lib/_vendor/authomatic/providers/openid.py index 6d39301e..344041f8 100755 --- a/rhodecode/lib/_vendor/authomatic/providers/openid.py +++ b/rhodecode/lib/_vendor/authomatic/providers/openid.py @@ -1,4 +1,3 @@ - """ |openid| Providers ---------------------------------- @@ -34,15 +33,14 @@ from authomatic import providers from authomatic.exceptions import FailureError, CancellationError, OpenIDError -__all__ = ['OpenID', 'Yahoo', 'Google'] +__all__ = ["OpenID", "Yahoo", "Google"] # Suppress openid logging. oidutil.log = lambda message, level=0: None -REALM_HTML = \ - """ +REALM_HTML = """ @@ -53,8 +51,7 @@ REALM_HTML = \ """ -XRDS_XML = \ - """ +XRDS_XML = """ rate: return with self.pipeline() as pipe: - pipe._send_stat(stat, '0|g', 1) - pipe._send_stat(stat, f'{value}|g', 1) + pipe._send_stat(stat, "0|g", 1) + pipe._send_stat(stat, f"{value}|g", 1) else: - prefix = '+' if delta and value >= 0 else '' - self._send_stat(stat, f'{prefix}{value}|g', rate, tags) + prefix = "+" if delta and value >= 0 else "" + self._send_stat(stat, f"{prefix}{value}|g", rate, tags) def set(self, stat, value, rate=1): """Set a set value.""" - self._send_stat(stat, f'{value}|s', rate) + self._send_stat(stat, f"{value}|s", rate) def histogram(self, stat, value, rate=1, tags=None): """Set a histogram""" - self._send_stat(stat, f'{value}|h', rate, tags) + self._send_stat(stat, f"{value}|h", rate, tags) def _send_stat(self, stat, value, rate, tags=None): self._after(self._prepare(stat, value, rate, tags)) @@ -108,12 +106,12 @@ class StatsClientBase: if rate < 1: if random.random() > rate: return - value = f'{value}|@{rate}' + value = f"{value}|@{rate}" if self._prefix: - stat = f'{self._prefix}.{stat}' + stat = f"{self._prefix}.{stat}" - res = '%s:%s%s' % ( + res = "%s:%s%s" % ( stat, value, ("|#" + ",".join(normalize_tags(tags))) if tags else "", @@ -126,7 +124,6 @@ class StatsClientBase: class PipelineBase(StatsClientBase): - def __init__(self, client): self._client = client self._prefix = client._prefix diff --git a/rhodecode/lib/_vendor/statsd/stream.py b/rhodecode/lib/_vendor/statsd/stream.py index 79951d25..f8967656 100644 --- a/rhodecode/lib/_vendor/statsd/stream.py +++ b/rhodecode/lib/_vendor/statsd/stream.py @@ -5,7 +5,7 @@ from .base import StatsClientBase, PipelineBase class StreamPipeline(PipelineBase): def _send(self): - self._client._after('\n'.join(self._stats)) + self._client._after("\n".join(self._stats)) self._stats.clear() @@ -14,7 +14,7 @@ class StreamClientBase(StatsClientBase): raise NotImplementedError() def close(self): - if self._sock and hasattr(self._sock, 'close'): + if self._sock and hasattr(self._sock, "close"): self._sock.close() self._sock = None @@ -32,14 +32,13 @@ class StreamClientBase(StatsClientBase): self._do_send(data) def _do_send(self, data): - self._sock.sendall(data.encode('ascii') + b'\n') + self._sock.sendall(data.encode("ascii") + b"\n") class TCPStatsClient(StreamClientBase): """TCP version of StatsClient.""" - def __init__(self, host='localhost', port=8125, prefix=None, - timeout=None, ipv6=False): + def __init__(self, host="localhost", port=8125, prefix=None, timeout=None, ipv6=False): """Create a new client.""" self._host = host self._port = port @@ -50,8 +49,7 @@ class TCPStatsClient(StreamClientBase): def connect(self): fam = socket.AF_INET6 if self._ipv6 else socket.AF_INET - family, _, _, _, addr = socket.getaddrinfo( - self._host, self._port, fam, socket.SOCK_STREAM)[0] + family, _, _, _, addr = socket.getaddrinfo(self._host, self._port, fam, socket.SOCK_STREAM)[0] self._sock = socket.socket(family, socket.SOCK_STREAM) self._sock.settimeout(self._timeout) self._sock.connect(addr) diff --git a/rhodecode/lib/_vendor/statsd/timer.py b/rhodecode/lib/_vendor/statsd/timer.py index 90ffd68e..627ac3c2 100644 --- a/rhodecode/lib/_vendor/statsd/timer.py +++ b/rhodecode/lib/_vendor/statsd/timer.py @@ -25,6 +25,7 @@ class Timer: def __call__(self, f): """Thread-safe timing function decorator.""" + @safe_wraps(f) def _wrapped(*args, **kwargs): start_time = time_now() @@ -34,6 +35,7 @@ class Timer: elapsed_time_ms = 1000.0 * (time_now() - start_time) self.client.timing(self.stat, elapsed_time_ms, self.rate, self.tags, self.use_decimals) self._sent = True + return _wrapped def __enter__(self): @@ -50,7 +52,7 @@ class Timer: def stop(self, send=True): if self._start_time is None: - raise RuntimeError('Timer has not started.') + raise RuntimeError("Timer has not started.") dt = time_now() - self._start_time self.ms = 1000.0 * dt # Convert to milliseconds. if send: @@ -59,8 +61,8 @@ class Timer: def send(self): if self.ms is None: - raise RuntimeError('No data recorded.') + raise RuntimeError("No data recorded.") if self._sent: - raise RuntimeError('Already sent data.') + raise RuntimeError("Already sent data.") self._sent = True self.client.timing(self.stat, self.ms, self.rate, self.tags, self.use_decimals) diff --git a/rhodecode/lib/_vendor/statsd/udp.py b/rhodecode/lib/_vendor/statsd/udp.py index 427481de..6ace020d 100644 --- a/rhodecode/lib/_vendor/statsd/udp.py +++ b/rhodecode/lib/_vendor/statsd/udp.py @@ -4,7 +4,6 @@ from .base import StatsClientBase, PipelineBase class Pipeline(PipelineBase): - def __init__(self, client): super().__init__(client) self._maxudpsize = client._maxudpsize @@ -18,19 +17,17 @@ class Pipeline(PipelineBase): self._client._after(data) data = stat else: - data += '\n' + stat + data += "\n" + stat self._client._after(data) class StatsClient(StatsClientBase): """A client for statsd.""" - def __init__(self, host='localhost', port=8125, prefix=None, - maxudpsize=512, ipv6=False): + def __init__(self, host="localhost", port=8125, prefix=None, maxudpsize=512, ipv6=False): """Create a new client.""" fam = socket.AF_INET6 if ipv6 else socket.AF_INET - family, _, _, _, addr = socket.getaddrinfo( - host, port, fam, socket.SOCK_DGRAM)[0] + family, _, _, _, addr = socket.getaddrinfo(host, port, fam, socket.SOCK_DGRAM)[0] self._addr = addr self._sock = socket.socket(family, socket.SOCK_DGRAM) self._prefix = prefix @@ -39,13 +36,13 @@ class StatsClient(StatsClientBase): def _send(self, data): """Send data to statsd.""" try: - self._sock.sendto(data.encode('ascii'), self._addr) + self._sock.sendto(data.encode("ascii"), self._addr) except (socket.error, RuntimeError): # No time for love, Dr. Jones! pass def close(self): - if self._sock and hasattr(self._sock, 'close'): + if self._sock and hasattr(self._sock, "close"): self._sock.close() self._sock = None diff --git a/rhodecode/lib/_vendor/webhelpers_backports/__init__.py b/rhodecode/lib/_vendor/webhelpers_backports/__init__.py index d86357c8..91c6f370 100644 --- a/rhodecode/lib/_vendor/webhelpers_backports/__init__.py +++ b/rhodecode/lib/_vendor/webhelpers_backports/__init__.py @@ -134,4 +134,4 @@ def raw_select(name, selected_values, options, id=NotGiven, **attrs): prompt = attrs.pop("prompt", None) if prompt or not isinstance(options, Options): options = Options(options, prompt=prompt) - return HTML.tag("select", NL, options.render(selected_values), **attrs) \ No newline at end of file + return HTML.tag("select", NL, options.render(selected_values), **attrs) diff --git a/rhodecode/lib/action_parser.py b/rhodecode/lib/action_parser.py index ae3cc158..6ab1dfc1 100644 --- a/rhodecode/lib/action_parser.py +++ b/rhodecode/lib/action_parser.py @@ -38,7 +38,7 @@ def action_parser(request, user_log, feed=False, parse_cs=False): :param feed: use output for feeds (no html and fancy icons) :param parse_cs: parse Changesets into VCS instances """ - if user_log.version == 'v2': + if user_log.version == "v2": ap = AuditLogParser(request, user_log) return ap.callbacks() else: @@ -48,7 +48,6 @@ def action_parser(request, user_log, feed=False, parse_cs=False): class ActionParser(object): - commits_limit = 3 # display this amount always commits_top_limit = 50 # show up to this amount of commits hidden @@ -59,115 +58,92 @@ class ActionParser(object): self.request = request self.action = user_log.action - self.action_params = ' ' - x = self.action.split(':', 1) + self.action_params = " " + x = self.action.split(":", 1) if len(x) > 1: self.action, self.action_params = x def callbacks(self): action_str = self.action_map.get(self.action, self.action) if self.feed: - action = action_str[0].replace('[', '').replace(']', '') + action = action_str[0].replace("[", "").replace("]", "") else: - action = action_str[0]\ - .replace('[', '')\ - .replace(']', '') + action = action_str[0].replace("[", '').replace("]", "") action_params_func = _no_params_func if callable(action_str[1]): action_params_func = action_str[1] # returned callbacks we need to call to get - return [ - lambda: literal(action), action_params_func, - self.action_parser_icon] + return [lambda: literal(action), action_params_func, self.action_parser_icon] @property def action_map(self): _ = self.request.translate # action : translated str, callback(extractor), icon action_map = { - 'user_deleted_repo': ( - _('[deleted] repository'), - None, 'icon-trash'), - 'user_created_repo': ( - _('[created] repository'), - None, 'icon-plus icon-plus-colored'), - 'user_created_fork': ( - _('[created] repository as fork'), - None, 'icon-code-fork'), - 'user_forked_repo': ( - _('[forked] repository'), - self.get_fork_name, 'icon-code-fork'), - 'user_updated_repo': ( - _('[updated] repository'), - None, 'icon-pencil icon-pencil-colored'), - 'user_downloaded_archive': ( - _('[downloaded] archive from repository'), - self.get_archive_name, 'icon-download-alt'), - 'admin_deleted_repo': ( - _('[delete] repository'), - None, 'icon-trash'), - 'admin_created_repo': ( - _('[created] repository'), - None, 'icon-plus icon-plus-colored'), - 'admin_forked_repo': ( - _('[forked] repository'), - None, 'icon-code-fork icon-fork-colored'), - 'admin_updated_repo': ( - _('[updated] repository'), - None, 'icon-pencil icon-pencil-colored'), - 'admin_created_user': ( - _('[created] user'), - self.get_user_name, 'icon-user icon-user-colored'), - 'admin_updated_user': ( - _('[updated] user'), - self.get_user_name, 'icon-user icon-user-colored'), - 'admin_created_users_group': ( - _('[created] user group'), - self.get_users_group, 'icon-pencil icon-pencil-colored'), - 'admin_updated_users_group': ( - _('[updated] user group'), - self.get_users_group, 'icon-pencil icon-pencil-colored'), - 'user_commented_revision': ( - _('[commented] on commit in repository'), - self.get_cs_links, 'icon-comment icon-comment-colored'), - 'user_commented_pull_request': ( - _('[commented] on pull request for'), - self.get_pull_request, 'icon-comment icon-comment-colored'), - 'user_closed_pull_request': ( - _('[closed] pull request for'), - self.get_pull_request, 'icon-check'), - 'user_merged_pull_request': ( - _('[merged] pull request for'), - self.get_pull_request, 'icon-check'), - 'push': ( - _('[pushed] into'), - self.get_cs_links, 'icon-arrow-up'), - 'push_local': ( - _('[committed via RhodeCode] into repository'), - self.get_cs_links, 'icon-pencil icon-pencil-colored'), - 'push_remote': ( - _('[pulled from remote] into repository'), - self.get_cs_links, 'icon-arrow-up'), - 'pull': ( - _('[pulled] from'), - None, 'icon-arrow-down'), - 'started_following_repo': ( - _('[started following] repository'), - None, 'icon-heart icon-heart-colored'), - 'stopped_following_repo': ( - _('[stopped following] repository'), - None, 'icon-heart-empty icon-heart-colored'), + "user_deleted_repo": (_("[deleted] repository"), None, "icon-trash"), + "user_created_repo": (_("[created] repository"), None, "icon-plus icon-plus-colored"), + "user_created_fork": (_("[created] repository as fork"), None, "icon-code-fork"), + "user_forked_repo": (_("[forked] repository"), self.get_fork_name, "icon-code-fork"), + "user_updated_repo": (_("[updated] repository"), None, "icon-pencil icon-pencil-colored"), + "user_downloaded_archive": ( + _("[downloaded] archive from repository"), + self.get_archive_name, + "icon-download-alt", + ), + "admin_deleted_repo": (_("[delete] repository"), None, "icon-trash"), + "admin_created_repo": (_("[created] repository"), None, "icon-plus icon-plus-colored"), + "admin_forked_repo": (_("[forked] repository"), None, "icon-code-fork icon-fork-colored"), + "admin_updated_repo": (_("[updated] repository"), None, "icon-pencil icon-pencil-colored"), + "admin_created_user": (_("[created] user"), self.get_user_name, "icon-user icon-user-colored"), + "admin_updated_user": (_("[updated] user"), self.get_user_name, "icon-user icon-user-colored"), + "admin_created_users_group": ( + _("[created] user group"), + self.get_users_group, + "icon-pencil icon-pencil-colored", + ), + "admin_updated_users_group": ( + _("[updated] user group"), + self.get_users_group, + "icon-pencil icon-pencil-colored", + ), + "user_commented_revision": ( + _("[commented] on commit in repository"), + self.get_cs_links, + "icon-comment icon-comment-colored", + ), + "user_commented_pull_request": ( + _("[commented] on pull request for"), + self.get_pull_request, + "icon-comment icon-comment-colored", + ), + "user_closed_pull_request": (_("[closed] pull request for"), self.get_pull_request, "icon-check"), + "user_merged_pull_request": (_("[merged] pull request for"), self.get_pull_request, "icon-check"), + "push": (_("[pushed] into"), self.get_cs_links, "icon-arrow-up"), + "push_local": ( + _("[committed via RhodeCode] into repository"), + self.get_cs_links, + "icon-pencil icon-pencil-colored", + ), + "push_remote": (_("[pulled from remote] into repository"), self.get_cs_links, "icon-arrow-up"), + "pull": (_("[pulled] from"), None, "icon-arrow-down"), + "started_following_repo": (_("[started following] repository"), None, "icon-heart icon-heart-colored"), + "stopped_following_repo": ( + _("[stopped following] repository"), + None, + "icon-heart-empty icon-heart-colored", + ), } return action_map def get_fork_name(self): from rhodecode.lib import helpers as h + _ = self.request.translate repo_name = self.action_params - _url = h.route_path('repo_summary', repo_name=repo_name) - return _('fork name %s') % link_to(self.action_params, _url) + _url = h.route_path("repo_summary", repo_name=repo_name) + return _("fork name %s") % link_to(self.action_params, _url) def get_user_name(self): user_name = self.action_params @@ -179,6 +155,7 @@ class ActionParser(object): def get_pull_request(self): from rhodecode.lib import helpers as h + _ = self.request.translate pull_request_id = self.action_params if self.is_deleted(): @@ -186,9 +163,9 @@ class ActionParser(object): else: repo_name = self.user_log.repository.repo_name return link_to( - _('Pull request #%s') % pull_request_id, - h.route_path('pullrequest_show', repo_name=repo_name, - pull_request_id=pull_request_id)) + _("Pull request #%s") % pull_request_id, + h.route_path("pullrequest_show", repo_name=repo_name, pull_request_id=pull_request_id), + ) def get_archive_name(self): archive_name = self.action_params @@ -196,60 +173,51 @@ class ActionParser(object): def action_parser_icon(self): tmpl = """""" - ico = self.action_map.get(self.action, ['', '', ''])[2] + ico = self.action_map.get(self.action, ["", "", ""])[2] return literal(tmpl % (ico, self.action)) def get_cs_links(self): from rhodecode.lib import helpers as h + _ = self.request.translate if self.is_deleted(): return self.action_params repo_name = self.user_log.repository.repo_name - commit_ids = self.action_params.split(',') + commit_ids = self.action_params.split(",") commits = self.get_commits(commit_ids) - link_generator = ( - self.lnk(commit, repo_name) - for commit in commits[:self.commits_limit]) - commit_links = [" " + ', '.join(link_generator)] + link_generator = (self.lnk(commit, repo_name) for commit in commits[: self.commits_limit]) + commit_links = [" " + ", ".join(link_generator)] _op1, _name1 = _get_op(commit_ids[0]) _op2, _name2 = _get_op(commit_ids[-1]) - commit_id_range = '%s...%s' % (_name1, _name2) + commit_id_range = "%s...%s" % (_name1, _name2) - compare_view = ( - '
' - '%s
' % ( - _('Show all combined commits %s->%s') % ( - commit_ids[0][:12], commit_ids[-1][:12] - ), - h.route_path( - 'repo_commit', repo_name=repo_name, - commit_id=commit_id_range), _('compare view') - ) + compare_view = ' ' % ( + _("Show all combined commits %s->%s") % (commit_ids[0][:12], commit_ids[-1][:12]), + h.route_path("repo_commit", repo_name=repo_name, commit_id=commit_id_range), + _("compare view"), ) if len(commit_ids) > self.commits_limit: more_count = len(commit_ids) - self.commits_limit - commit_links.append( - _(' and %(num)s more commits') % {'num': more_count} - ) + commit_links.append(_(" and %(num)s more commits") % {"num": more_count}) if len(commits) > 1: commit_links.append(compare_view) - return ''.join(commit_links) + return "".join(commit_links) def get_commits(self, commit_ids): commits = [] - if not [v for v in commit_ids if v != '']: + if not [v for v in commit_ids if v != ""]: return commits repo = None if self.parse_commits: repo = self.user_log.repository.scm_instance() - for commit_id in commit_ids[:self.commits_top_limit]: + for commit_id in commit_ids[: self.commits_top_limit]: _op, _name = _get_op(commit_id) # we want parsed commits, or new log store format is bad @@ -258,18 +226,13 @@ class ActionParser(object): commit = repo.get_commit(commit_id=commit_id) commits.append(commit) except CommitDoesNotExistError: - log.error('cannot find commit id %s in this repository', - commit_id) + log.error("cannot find commit id %s in this repository", commit_id) commits.append(commit_id) continue else: - fake_commit = AttributeDict({ - 'short_id': commit_id[:12], - 'raw_id': commit_id, - 'message': '', - 'op': _op, - 'ref_name': _name - }) + fake_commit = AttributeDict( + {"short_id": commit_id[:12], "raw_id": commit_id, "message": "", "op": _op, "ref_name": _name} + ) commits.append(fake_commit) return commits @@ -277,37 +240,35 @@ class ActionParser(object): def lnk(self, commit_or_id, repo_name): from rhodecode.lib.helpers import tooltip from rhodecode.lib import helpers as h + _ = self.request.translate - title = '' + title = "" lazy_cs = True if isinstance(commit_or_id, (BaseCommit, AttributeDict)): lazy_cs = True - if (getattr(commit_or_id, 'op', None) and - getattr(commit_or_id, 'ref_name', None)): + if getattr(commit_or_id, "op", None) and getattr(commit_or_id, "ref_name", None): lazy_cs = False - lbl = '?' - if commit_or_id.op == 'delete_branch': - lbl = '%s' % _('Deleted branch: %s') % commit_or_id.ref_name - title = '' - elif commit_or_id.op == 'tag': - lbl = '%s' % _('Created tag: %s') % commit_or_id.ref_name - title = '' - _url = '#' + lbl = "?" + if commit_or_id.op == "delete_branch": + lbl = "%s" % _("Deleted branch: %s") % commit_or_id.ref_name + title = "" + elif commit_or_id.op == "tag": + lbl = "%s" % _("Created tag: %s") % commit_or_id.ref_name + title = "" + _url = "#" else: - lbl = '%s' % (commit_or_id.short_id[:8]) - _url = h.route_path('repo_commit', repo_name=repo_name, - commit_id=commit_or_id.raw_id) + lbl = "%s" % (commit_or_id.short_id[:8]) + _url = h.route_path("repo_commit", repo_name=repo_name, commit_id=commit_or_id.raw_id) title = tooltip(commit_or_id.message) else: # commit cannot be found/striped/removed etc. - lbl = ('%s' % commit_or_id)[:12] - _url = '#' - title = _('Commit not found') + lbl = ("%s" % commit_or_id)[:12] + _url = "#" + title = _("Commit not found") if self.parse_commits: - return link_to(lbl, _url, title=title, class_='tooltip') - return link_to(lbl, _url, raw_id=commit_or_id.raw_id, repo_name=repo_name, - class_='lazy-cs' if lazy_cs else '') + return link_to(lbl, _url, title=title, class_="tooltip") + return link_to(lbl, _url, raw_id=commit_or_id.raw_id, repo_name=repo_name, class_="lazy-cs" if lazy_cs else "") def is_deleted(self): return self.user_log.repository is None @@ -319,16 +280,14 @@ class AuditLogParser(object): self.request = request def get_icon(self, action): - return 'icon-rhodecode' + return "icon-rhodecode" def callbacks(self): action_str = self.audit_log_entry.action def callback(): # returned callbacks we need to call to get - action = action_str \ - .replace('[', '')\ - .replace(']', '') + action = action_str.replace("[", '').replace("]", "") return literal(action) def icon(): @@ -338,8 +297,7 @@ class AuditLogParser(object): action_params_func = _no_params_func - return [ - callback, action_params_func, icon] + return [callback, action_params_func, icon] def _no_params_func(): @@ -349,6 +307,6 @@ def _no_params_func(): def _get_op(commit_id): _op = None _name = commit_id - if len(commit_id.split('=>')) == 2: - _op, _name = commit_id.split('=>') + if len(commit_id.split("=>")) == 2: + _op, _name = commit_id.split("=>") return _op, _name diff --git a/rhodecode/lib/archive_cache/__init__.py b/rhodecode/lib/archive_cache/__init__.py index d0cd5541..c685800b 100644 --- a/rhodecode/lib/archive_cache/__init__.py +++ b/rhodecode/lib/archive_cache/__init__.py @@ -22,7 +22,7 @@ from .backends.fanout_cache import FileSystemFanoutCache from .backends.objectstore_cache import ObjectStoreCache from .utils import archive_iterator # noqa -from .lock import ArchiveCacheGenerationLock # noqa +from .lock import ArchiveCacheGenerationLock # noqa log = logging.getLogger(__name__) @@ -39,40 +39,30 @@ def includeme(config): def get_archival_config(config): - - final_config = { - - } + final_config = {} for k, v in config.items(): - if k.startswith('archive_cache'): + if k.startswith("archive_cache"): final_config[k] = v return final_config def get_archival_cache_store(config, always_init=False): - global cache_meta if cache_meta is not None and not always_init: return cache_meta config = get_archival_config(config) - backend = config['archive_cache.backend.type'] + backend = config["archive_cache.backend.type"] - archive_cache_locking_url = config['archive_cache.locking.url'] + archive_cache_locking_url = config["archive_cache.locking.url"] match backend: - case 'filesystem': - d_cache = FileSystemFanoutCache( - locking_url=archive_cache_locking_url, - **config - ) - case 'objectstore': - d_cache = ObjectStoreCache( - locking_url=archive_cache_locking_url, - **config - ) + case "filesystem": + d_cache = FileSystemFanoutCache(locking_url=archive_cache_locking_url, **config) + case "objectstore": + d_cache = ObjectStoreCache(locking_url=archive_cache_locking_url, **config) case _: raise ValueError(f'archive_cache.backend.type only supports "filesystem" or "objectstore" got {backend} ') diff --git a/rhodecode/lib/archive_cache/backends/base.py b/rhodecode/lib/archive_cache/backends/base.py index 76c4688b..2a969339 100644 --- a/rhodecode/lib/archive_cache/backends/base.py +++ b/rhodecode/lib/archive_cache/backends/base.py @@ -31,7 +31,7 @@ log = logging.getLogger(__name__) class BaseShard: - storage_type: str = '' + storage_type: str = "" fs = None @classmethod @@ -43,7 +43,7 @@ class BaseShard: """ mask = 0xFFFFFFFF - return zlib.adler32(key.encode('utf-8')) & mask # noqa + return zlib.adler32(key.encode("utf-8")) & mask # noqa def _write_file(self, full_path, read_iterator, mode): raise NotImplementedError @@ -58,38 +58,36 @@ class BaseShard: raise NotImplementedError def _store(self, key, value_reader, metadata, mode): - (filename, # hash-name - full_path # full-path/hash-name - ) = self.random_filename() + ( + filename, # hash-name + full_path, # full-path/hash-name + ) = self.random_filename() key_file, key_file_path = self._get_keyfile(key) # STORE METADATA _metadata = { "version": "v1", - "key_file": key_file, # this is the .key.json file storing meta "key_file_path": key_file_path, # full path to key_file "archive_key": key, # original name we stored archive under, e.g my-archive.zip "archive_filename": filename, # the actual filename we stored that file under "archive_full_path": full_path, - "store_time": time.time(), "access_count": 0, "access_time": 0, - - "size": 0 + "size": 0, } if metadata: _metadata.update(metadata) - read_iterator = iter(functools.partial(value_reader.read, 2**22), b'') + read_iterator = iter(functools.partial(value_reader.read, 2**22), b"") size, sha256 = self._write_file(full_path, read_iterator, mode) - _metadata['size'] = size - _metadata['sha256'] = sha256 + _metadata["size"] = size + _metadata["sha256"] = sha256 # after archive is finished, we create a key to save the presence of the binary file - with self.fs.open(key_file_path, 'wb') as f: + with self.fs.open(key_file_path, "wb") as f: f.write(json.dumps(_metadata)) return key, filename, size, _metadata @@ -97,8 +95,9 @@ class BaseShard: def fetch(self, *args, **kwargs): raise NotImplementedError - def _fetch(self, key, retry, retry_attempts, retry_backoff, - presigned_url_expires: int = 0) -> tuple[ShardFileReader, dict]: + def _fetch( + self, key, retry, retry_attempts, retry_backoff, presigned_url_expires: int = 0 + ) -> tuple[ShardFileReader, dict]: if retry is NOT_GIVEN: retry = False if retry_attempts is NOT_GIVEN: @@ -112,26 +111,30 @@ class BaseShard: time.sleep(retry_backoff) if key not in self: - log.exception(f'requested key={key} not found in {self} retry={retry}, attempts={retry_attempts}') + log.exception(f"requested key={key} not found in {self} retry={retry}, attempts={retry_attempts}") raise KeyError(key) key_file, key_file_path = self._get_keyfile(key) - with self.fs.open(key_file_path, 'rb') as f: + with self.fs.open(key_file_path, "rb") as f: metadata = json.loads(f.read()) - archive_path = metadata['archive_full_path'] + archive_path = metadata["archive_full_path"] if presigned_url_expires and presigned_url_expires > 0: - metadata['url'] = self.fs.url(archive_path, expires=presigned_url_expires) + metadata["url"] = self.fs.url(archive_path, expires=presigned_url_expires) try: - return ShardFileReader(self.fs.open(archive_path, 'rb')), metadata + return ShardFileReader(self.fs.open(archive_path, "rb")), metadata finally: # update usage stats, count and accessed metadata["access_count"] = metadata.get("access_count", 0) + 1 metadata["access_time"] = time.time() - log.debug('Updated %s with access snapshot, access_count=%s access_time=%s', - key_file, metadata['access_count'], metadata['access_time']) - with self.fs.open(key_file_path, 'wb') as f: + log.debug( + "Updated %s with access snapshot, access_count=%s access_time=%s", + key_file, + metadata["access_count"], + metadata["access_time"], + ) + with self.fs.open(key_file_path, "wb") as f: f.write(json.dumps(metadata)) def remove(self, *args, **kwargs): @@ -139,14 +142,14 @@ class BaseShard: def _remove(self, key): if key not in self: - log.exception(f'requested key={key} not found in {self}') + log.exception(f"requested key={key} not found in {self}") raise KeyError(key) key_file, key_file_path = self._get_keyfile(key) - with self.fs.open(key_file_path, 'rb') as f: + with self.fs.open(key_file_path, "rb") as f: metadata = json.loads(f.read()) - archive_path = metadata['archive_full_path'] + archive_path = metadata["archive_full_path"] self.fs.rm(archive_path) self.fs.rm(key_file_path) return 1 @@ -157,7 +160,7 @@ class BaseShard: @property def key_suffix(self): - return 'key.json' + return "key.json" def __contains__(self, key): """Return `True` if `key` matching item is found in cache. @@ -171,8 +174,8 @@ class BaseShard: class BaseCache: - _locking_url: str = '' - _storage_path: str = '' + _locking_url: str = "" + _storage_path: str = "" _config: dict = {} retry = False retry_attempts: int = 0 @@ -192,11 +195,11 @@ class BaseCache: return self.has_key(key) def __repr__(self): - return f'<{self.__class__.__name__}(storage={self._storage_path})>' + return f"<{self.__class__.__name__}(storage={self._storage_path})>" @classmethod def gb_to_bytes(cls, gb): - return gb * (1024 ** 3) + return gb * (1024**3) @property def storage_path(self): @@ -238,10 +241,13 @@ class BaseCache: presigned_url_expires = self.presigned_url_expires shard = self._get_shard(key) - return shard.fetch(key, retry=retry, - retry_attempts=retry_attempts, - retry_backoff=retry_backoff, - presigned_url_expires=presigned_url_expires) + return shard.fetch( + key, + retry=retry, + retry_attempts=retry_attempts, + retry_backoff=retry_backoff, + presigned_url_expires=presigned_url_expires, + ) def remove(self, key): shard = self._get_shard(key) @@ -284,17 +290,13 @@ class BaseCache: Then we run a sorting strategy based on eviction policy. We iterate over sorted keys, and remove each checking if we hit the overall limit. """ - removal_info = { - "removed_items": 0, - "removed_size": 0 - } + removal_info = {"removed_items": 0, "removed_size": 0} policy = policy or self._eviction_policy size_limit = size_limit or self._cache_size_limit - select_policy = EVICTION_POLICY[policy]['evict'] + select_policy = EVICTION_POLICY[policy]["evict"] - log.debug('Running eviction policy \'%s\', and checking for size limit: %s', - policy, format_size(size_limit)) + log.debug("Running eviction policy '%s', and checking for size limit: %s", policy, format_size(size_limit)) if select_policy is None: return removal_info @@ -305,38 +307,44 @@ class BaseCache: cnt = 1 for shard, key_file in self.iter_keys(): - with shard.fs.open(os.path.join(shard.storage_medium, key_file), 'rb') as f: + with shard.fs.open(os.path.join(shard.storage_medium, key_file), "rb") as f: metadata = json.loads(f.read()) key_file_path = os.path.join(shard.storage_medium, key_file) - archive_key = metadata['archive_key'] - archive_path = metadata['archive_full_path'] + archive_key = metadata["archive_key"] + archive_path = metadata["archive_full_path"] - size = metadata.get('size') + size = metadata.get("size") if not size: # in case we don't have size re-calc it... size = self._get_size(shard, archive_path) - data.append([ - cnt, - key_file, - key_file_path, - archive_key, - archive_path, - metadata.get('store_time', 0), - metadata.get('access_time', 0), - metadata.get('access_count', 0), - size, - ]) + data.append( + [ + cnt, + key_file, + key_file_path, + archive_key, + archive_path, + metadata.get("store_time", 0), + metadata.get("access_time", 0), + metadata.get("access_count", 0), + size, + ] + ) cnt += 1 # Insert bulk data using executemany db.bulk_insert(data) total_size = db.get_total_size() - log.debug('Analyzed %s keys, occupying: %s, running eviction to match %s', - len(data), format_size(total_size), format_size(size_limit)) + log.debug( + "Analyzed %s keys, occupying: %s, running eviction to match %s", + len(data), + format_size(total_size), + format_size(size_limit), + ) removed_items = 0 removed_size = 0 @@ -351,10 +359,9 @@ class BaseCache: self.remove(archive_key) removed_items += 1 removed_size += size - removal_info['removed_items'] = removed_items - removal_info['removed_size'] = removed_size - log.debug('Removed %s cache archives, and reduced size by: %s', - removed_items, format_size(removed_size)) + removal_info["removed_items"] = removed_items + removal_info["removed_size"] = removed_size + log.debug("Removed %s cache archives, and reduced size by: %s", removed_items, format_size(removed_size)) return removal_info def get_statistics(self): @@ -364,9 +371,9 @@ class BaseCache: for shard, key_file in self.iter_keys(): json_key = f"{shard.storage_medium}/{key_file}" - with shard.fs.open(json_key, 'rb') as f: + with shard.fs.open(json_key, "rb") as f: total_files += 1 metadata = json.loads(f.read()) - total_size += metadata['size'] + total_size += metadata["size"] return total_files, total_size, meta diff --git a/rhodecode/lib/archive_cache/backends/fanout_cache.py b/rhodecode/lib/archive_cache/backends/fanout_cache.py index 1a786f64..3f5af49e 100644 --- a/rhodecode/lib/archive_cache/backends/fanout_cache.py +++ b/rhodecode/lib/archive_cache/backends/fanout_cache.py @@ -32,12 +32,11 @@ log = logging.getLogger(__name__) class FileSystemShard(BaseShard): - def __init__(self, index, directory, directory_folder, fs, **settings): self._index: int = index self._directory: str = directory self._directory_folder: str = directory_folder - self.storage_type: str = 'directory' + self.storage_type: str = "directory" self.fs = fs @@ -47,7 +46,7 @@ class FileSystemShard(BaseShard): return os.path.join(self._directory, self._directory_folder) def _get_keyfile(self, archive_key) -> tuple[str, str]: - key_file: str = f'{archive_key}.{self.key_suffix}' + key_file: str = f"{archive_key}.{self.key_suffix}" return key_file, os.path.join(self.directory, key_file) def _get_writer(self, path, mode): @@ -63,7 +62,6 @@ class FileSystemShard(BaseShard): continue def _write_file(self, full_path, iterator, mode): - # ensure dir exists destination, _ = os.path.split(full_path) if not self.fs.exists(destination): @@ -85,14 +83,15 @@ class FileSystemShard(BaseShard): # Sync the file descriptor to disk, helps with NFS cases... os.fsync(fd) sha256 = digest.hexdigest() - log.debug('written new archive cache under %s, sha256: %s', full_path, sha256) + log.debug("written new archive cache under %s, sha256: %s", full_path, sha256) return size, sha256 def store(self, key, value_reader, metadata: dict | None = None): - return self._store(key, value_reader, metadata, mode='xb') + return self._store(key, value_reader, metadata, mode="xb") - def fetch(self, key, retry=NOT_GIVEN, - retry_attempts=NOT_GIVEN, retry_backoff=1, **kwargs) -> tuple[ShardFileReader, dict]: + def fetch( + self, key, retry=NOT_GIVEN, retry_attempts=NOT_GIVEN, retry_backoff=1, **kwargs + ) -> tuple[ShardFileReader, dict]: return self._fetch(key, retry, retry_attempts, retry_backoff) def remove(self, key): @@ -107,20 +106,20 @@ class FileSystemShard(BaseShard): directories with many files may be slow. """ - hex_name = codecs.encode(os.urandom(16), 'hex').decode('utf-8') + hex_name = codecs.encode(os.urandom(16), "hex").decode("utf-8") - archive_name = hex_name[4:] + '.archive_cache' + archive_name = hex_name[4:] + ".archive_cache" filename = f"{hex_name[:2]}/{hex_name[2:4]}/{archive_name}" full_path = os.path.join(self.directory, filename) return archive_name, full_path def __repr__(self): - return f'{self.__class__.__name__}(index={self._index}, dir={self.directory})' + return f"{self.__class__.__name__}(index={self._index}, dir={self.directory})" class FileSystemFanoutCache(BaseCache): - shard_name: str = 'shard_{:03d}' + shard_name: str = "shard_{:03d}" shard_cls = FileSystemShard def __init__(self, locking_url, **settings): @@ -133,26 +132,26 @@ class FileSystemFanoutCache(BaseCache): """ self._locking_url = locking_url self._config = settings - cache_dir = self.get_conf('archive_cache.filesystem.store_dir') + cache_dir = self.get_conf("archive_cache.filesystem.store_dir") directory = str(cache_dir) directory = os.path.expanduser(directory) directory = os.path.expandvars(directory) self._directory = directory self._storage_path = directory # common path for all from BaseCache - self._shard_count = int(self.get_conf('archive_cache.filesystem.cache_shards', pop=True)) + self._shard_count = int(self.get_conf("archive_cache.filesystem.cache_shards", pop=True)) if self._shard_count < 1: - raise ValueError('cache_shards must be 1 or more') + raise ValueError("cache_shards must be 1 or more") - self._eviction_policy = self.get_conf('archive_cache.filesystem.eviction_policy', pop=True) - self._cache_size_limit = self.gb_to_bytes(int(self.get_conf('archive_cache.filesystem.cache_size_gb'))) + self._eviction_policy = self.get_conf("archive_cache.filesystem.eviction_policy", pop=True) + self._cache_size_limit = self.gb_to_bytes(int(self.get_conf("archive_cache.filesystem.cache_size_gb"))) - self.retry = str2bool(self.get_conf('archive_cache.filesystem.retry', pop=True)) - self.retry_attempts = int(self.get_conf('archive_cache.filesystem.retry_attempts', pop=True)) - self.retry_backoff = int(self.get_conf('archive_cache.filesystem.retry_backoff', pop=True)) + self.retry = str2bool(self.get_conf("archive_cache.filesystem.retry", pop=True)) + self.retry_attempts = int(self.get_conf("archive_cache.filesystem.retry_attempts", pop=True)) + self.retry_backoff = int(self.get_conf("archive_cache.filesystem.retry_backoff", pop=True)) - log.debug('Initializing %s archival cache instance', self) - fs = fsspec.filesystem('file') + log.debug("Initializing %s archival cache instance", self) + fs = fsspec.filesystem("file") # check if it's ok to write, and re-create the archive cache main dir # A directory is the virtual equivalent of a physical file cabinet. # In other words, it's a container for organizing digital data. diff --git a/rhodecode/lib/archive_cache/backends/objectstore_cache.py b/rhodecode/lib/archive_cache/backends/objectstore_cache.py index dceac413..548e4723 100644 --- a/rhodecode/lib/archive_cache/backends/objectstore_cache.py +++ b/rhodecode/lib/archive_cache/backends/objectstore_cache.py @@ -32,11 +32,10 @@ log = logging.getLogger(__name__) class S3Shard(BaseShard): - def __init__(self, index, bucket, bucket_folder, fs, **settings): self._index: int = index self._bucket_folder: str = bucket_folder - self.storage_type: str = 'bucket' + self.storage_type: str = "bucket" self._bucket_main: str = bucket self.fs = fs @@ -47,14 +46,13 @@ class S3Shard(BaseShard): return os.path.join(self._bucket_main, self._bucket_folder) def _get_keyfile(self, archive_key) -> tuple[str, str]: - key_file: str = f'{archive_key}-{self.key_suffix}' + key_file: str = f"{archive_key}-{self.key_suffix}" return key_file, os.path.join(self.bucket, key_file) def _get_writer(self, path, mode): - return self.fs.open(path, 'wb') + return self.fs.open(path, "wb") def _write_file(self, full_path, iterator, mode): - # ensure folder in bucket exists destination = self.bucket if not self.fs.exists(destination): @@ -71,15 +69,15 @@ class S3Shard(BaseShard): writer.write(chunk) sha256 = digest.hexdigest() - log.debug('written new archive cache under %s, sha256: %s', full_path, sha256) + log.debug("written new archive cache under %s, sha256: %s", full_path, sha256) return size, sha256 def store(self, key, value_reader, metadata: dict | None = None): - return self._store(key, value_reader, metadata, mode='wb') + return self._store(key, value_reader, metadata, mode="wb") - def fetch(self, key, retry=NOT_GIVEN, - retry_attempts=NOT_GIVEN, retry_backoff=1, - presigned_url_expires: int = 0) -> tuple[ShardFileReader, dict]: + def fetch( + self, key, retry=NOT_GIVEN, retry_attempts=NOT_GIVEN, retry_backoff=1, presigned_url_expires: int = 0 + ) -> tuple[ShardFileReader, dict]: return self._fetch(key, retry, retry_attempts, retry_backoff, presigned_url_expires=presigned_url_expires) def remove(self, key): @@ -94,20 +92,20 @@ class S3Shard(BaseShard): directories with many files may be slow. """ - hex_name = codecs.encode(os.urandom(16), 'hex').decode('utf-8') + hex_name = codecs.encode(os.urandom(16), "hex").decode("utf-8") - archive_name = hex_name[4:] + '.archive_cache' + archive_name = hex_name[4:] + ".archive_cache" filename = f"{hex_name[:2]}-{hex_name[2:4]}-{archive_name}" full_path = os.path.join(self.bucket, filename) return archive_name, full_path def __repr__(self): - return f'{self.__class__.__name__}(index={self._index}, bucket={self.bucket})' + return f"{self.__class__.__name__}(index={self._index}, bucket={self.bucket})" class ObjectStoreCache(BaseCache): - shard_name: str = 'shard-{:03d}' + shard_name: str = "shard-{:03d}" shard_cls = S3Shard def __init__(self, locking_url, **settings): @@ -121,33 +119,33 @@ class ObjectStoreCache(BaseCache): self._locking_url = locking_url self._config = settings - objectstore_url = self.get_conf('archive_cache.objectstore.url') + objectstore_url = self.get_conf("archive_cache.objectstore.url") self._storage_path = objectstore_url # common path for all from BaseCache - self._shard_count = int(self.get_conf('archive_cache.objectstore.bucket_shards', pop=True)) + self._shard_count = int(self.get_conf("archive_cache.objectstore.bucket_shards", pop=True)) if self._shard_count < 1: - raise ValueError('cache_shards must be 1 or more') + raise ValueError("cache_shards must be 1 or more") - self._bucket = settings.pop('archive_cache.objectstore.bucket') + self._bucket = settings.pop("archive_cache.objectstore.bucket") if not self._bucket: - raise ValueError('archive_cache.objectstore.bucket needs to have a value') + raise ValueError("archive_cache.objectstore.bucket needs to have a value") - self._eviction_policy = self.get_conf('archive_cache.objectstore.eviction_policy', pop=True) - self._cache_size_limit = self.gb_to_bytes(int(self.get_conf('archive_cache.objectstore.cache_size_gb'))) + self._eviction_policy = self.get_conf("archive_cache.objectstore.eviction_policy", pop=True) + self._cache_size_limit = self.gb_to_bytes(int(self.get_conf("archive_cache.objectstore.cache_size_gb"))) - self.retry = str2bool(self.get_conf('archive_cache.objectstore.retry', pop=True)) - self.retry_attempts = int(self.get_conf('archive_cache.objectstore.retry_attempts', pop=True)) - self.retry_backoff = int(self.get_conf('archive_cache.objectstore.retry_backoff', pop=True)) + self.retry = str2bool(self.get_conf("archive_cache.objectstore.retry", pop=True)) + self.retry_attempts = int(self.get_conf("archive_cache.objectstore.retry_attempts", pop=True)) + self.retry_backoff = int(self.get_conf("archive_cache.objectstore.retry_backoff", pop=True)) - endpoint_url = settings.pop('archive_cache.objectstore.url') - key = settings.pop('archive_cache.objectstore.key') - secret = settings.pop('archive_cache.objectstore.secret') - region = settings.pop('archive_cache.objectstore.region') + endpoint_url = settings.pop("archive_cache.objectstore.url") + key = settings.pop("archive_cache.objectstore.key") + secret = settings.pop("archive_cache.objectstore.secret") + region = settings.pop("archive_cache.objectstore.region") - log.debug('Initializing %s archival cache instance', self) + log.debug("Initializing %s archival cache instance", self) fs = fsspec.filesystem( - 's3', anon=False, endpoint_url=endpoint_url, key=key, secret=secret, client_kwargs={'region_name': region} + "s3", anon=False, endpoint_url=endpoint_url, key=key, secret=secret, client_kwargs={"region_name": region} ) # init main bucket @@ -167,7 +165,7 @@ class ObjectStoreCache(BaseCache): self._hash = self._shards[0].hash def _get_size(self, shard, archive_path): - return shard.fs.info(archive_path)['size'] + return shard.fs.info(archive_path)["size"] def set_presigned_url_expiry(self, val: int) -> None: self.presigned_url_expires = val diff --git a/rhodecode/lib/archive_cache/lock.py b/rhodecode/lib/archive_cache/lock.py index f79d8820..77dcdad7 100644 --- a/rhodecode/lib/archive_cache/lock.py +++ b/rhodecode/lib/archive_cache/lock.py @@ -31,6 +31,7 @@ class GenerationLock: with GenerationLock(lock_key): compute_archive() """ + lock_timeout = 7200 def __init__(self, lock_key, url): @@ -40,23 +41,18 @@ class GenerationLock: def _create_client(self, url): connection_pool = redis.ConnectionPool.from_url(url) - self.writer_client = redis.StrictRedis( - connection_pool=connection_pool - ) + self.writer_client = redis.StrictRedis(connection_pool=connection_pool) self.reader_client = self.writer_client def get_lock(self): return redis_lock.Lock( - redis_client=self.writer_client, - name=self.lock_key, - expire=self.lock_timeout, - strict=True + redis_client=self.writer_client, name=self.lock_key, expire=self.lock_timeout, strict=True ) def __enter__(self): acquired = self.lock.acquire(blocking=False) if not acquired: - raise ArchiveCacheGenerationLock('Failed to create a lock') + raise ArchiveCacheGenerationLock("Failed to create a lock") def __exit__(self, exc_type, exc_val, exc_tb): self.lock.release() diff --git a/rhodecode/lib/archive_cache/utils.py b/rhodecode/lib/archive_cache/utils.py index 8e46ec7a..2ab6b7cc 100644 --- a/rhodecode/lib/archive_cache/utils.py +++ b/rhodecode/lib/archive_cache/utils.py @@ -23,17 +23,17 @@ NOT_GIVEN = -917 EVICTION_POLICY = { - 'none': { - 'evict': None, + "none": { + "evict": None, }, - 'least-recently-stored': { - 'evict': 'SELECT {fields} FROM archive_cache ORDER BY store_time', + "least-recently-stored": { + "evict": "SELECT {fields} FROM archive_cache ORDER BY store_time", }, - 'least-recently-used': { - 'evict': 'SELECT {fields} FROM archive_cache ORDER BY access_time', + "least-recently-used": { + "evict": "SELECT {fields} FROM archive_cache ORDER BY access_time", }, - 'least-frequently-used': { - 'evict': 'SELECT {fields} FROM archive_cache ORDER BY access_count', + "least-frequently-used": { + "evict": "SELECT {fields} FROM archive_cache ORDER BY access_count", }, } @@ -49,20 +49,19 @@ def archive_iterator(_reader, block_size: int = 4096 * 512): def format_size(size): # Convert size in bytes to a human-readable format (e.g., KB, MB, GB) - for unit in ['B', 'KB', 'MB', 'GB', 'TB']: + for unit in ["B", "KB", "MB", "GB", "TB"]: if size < 1024: return f"{size:.2f} {unit}" size /= 1024 class StatsDB: - def __init__(self): - self.connection = sqlite3.connect(':memory:') + self.connection = sqlite3.connect(":memory:") self._init_db() def _init_db(self): - qry = ''' + qry = """ CREATE TABLE IF NOT EXISTS archive_cache ( rowid INTEGER PRIMARY KEY, key_file TEXT, @@ -74,7 +73,7 @@ class StatsDB: access_count INTEGER DEFAULT 0, size INTEGER DEFAULT 0 ) - ''' + """ self.sql(qry) self.connection.commit() @@ -84,7 +83,7 @@ class StatsDB: return self.connection.execute def bulk_insert(self, rows): - qry = ''' + qry = """ INSERT INTO archive_cache ( rowid, key_file, @@ -99,30 +98,29 @@ class StatsDB: VALUES ( ?, ?, ?, ?, ?, ?, ?, ?, ? ) - ''' + """ cursor = self.connection.cursor() cursor.executemany(qry, rows) self.connection.commit() def get_total_size(self): - qry = 'SELECT COALESCE(SUM(size), 0) FROM archive_cache' + qry = "SELECT COALESCE(SUM(size), 0) FROM archive_cache" ((total_size,),) = self.sql(qry).fetchall() return total_size def get_sorted_keys(self, select_policy): - select_policy_qry = select_policy.format(fields='key_file, archive_key, size') + select_policy_qry = select_policy.format(fields="key_file, archive_key, size") return self.sql(select_policy_qry).fetchall() class ShardFileReader: - def __init__(self, file_like_reader): self._file_like_reader = file_like_reader def __getattr__(self, item): if isinstance(self._file_like_reader, s3fs.core.S3File): match item: - case 'name': + case "name": # S3 FileWrapper doesn't support name attribute, and we use it return self._file_like_reader.full_name case _: @@ -131,4 +129,4 @@ class ShardFileReader: return getattr(self._file_like_reader, item) def __repr__(self): - return f'<{self.__class__.__name__}={self._file_like_reader}>' + return f"<{self.__class__.__name__}={self._file_like_reader}>" diff --git a/rhodecode/lib/audit_logger.py b/rhodecode/lib/audit_logger.py index e14d7d70..ad24483d 100644 --- a/rhodecode/lib/audit_logger.py +++ b/rhodecode/lib/audit_logger.py @@ -29,86 +29,74 @@ log = logging.getLogger(__name__) # action as key, and expected action_data as value ACTIONS_V1 = { - 'user.login.success': {'user_agent': ''}, - 'user.login.failure': {'user_agent': ''}, - 'user.logout': {'user_agent': ''}, - 'user.register': {}, - 'user.password.reset_request': {}, - 'user.push': {'user_agent': '', 'commit_ids': []}, - 'user.pull': {'user_agent': ''}, - - 'user.create': {'data': {}}, - 'user.delete': {'old_data': {}}, - 'user.edit': {'old_data': {}}, - 'user.edit.permissions': {}, - 'user.edit.ip.add': {'ip': {}, 'user': {}}, - 'user.edit.ip.delete': {'ip': {}, 'user': {}}, - 'user.edit.token.add': {'token': {}, 'user': {}}, - 'user.edit.token.delete': {'token': {}, 'user': {}}, - 'user.edit.email.add': {'email': ''}, - 'user.edit.email.delete': {'email': ''}, - 'user.edit.ssh_key.add': {'token': {}, 'user': {}}, - 'user.edit.ssh_key.delete': {'token': {}, 'user': {}}, - 'user.edit.password_reset.enabled': {}, - 'user.edit.password_reset.disabled': {}, - - 'user_group.create': {'data': {}}, - 'user_group.delete': {'old_data': {}}, - 'user_group.edit': {'old_data': {}}, - 'user_group.edit.permissions': {}, - 'user_group.edit.member.add': {'user': {}}, - 'user_group.edit.member.delete': {'user': {}}, - - 'repo.create': {'data': {}}, - 'repo.fork': {'data': {}}, - 'repo.edit': {'old_data': {}}, - 'repo.edit.permissions': {}, - 'repo.edit.permissions.branch': {}, - 'repo.archive': {'old_data': {}}, - 'repo.delete': {'old_data': {}}, - - 'repo.archive.download': {'user_agent': '', 'archive_name': '', - 'archive_spec': '', 'archive_cached': ''}, - - 'repo.permissions.branch_rule.create': {}, - 'repo.permissions.branch_rule.edit': {}, - 'repo.permissions.branch_rule.delete': {}, - - 'repo.pull_request.create': '', - 'repo.pull_request.edit': '', - 'repo.pull_request.delete': '', - 'repo.pull_request.close': '', - 'repo.pull_request.merge': '', - 'repo.pull_request.vote': '', - 'repo.pull_request.comment.create': '', - 'repo.pull_request.comment.edit': '', - 'repo.pull_request.comment.delete': '', - - 'repo.pull_request.reviewer.add': '', - 'repo.pull_request.reviewer.delete': '', - - 'repo.pull_request.observer.add': '', - 'repo.pull_request.observer.delete': '', - - 'repo.commit.strip': {'commit_id': ''}, - 'repo.commit.comment.create': {'data': {}}, - 'repo.commit.comment.delete': {'data': {}}, - 'repo.commit.comment.edit': {'data': {}}, - 'repo.commit.vote': '', - - 'repo.artifact.add': '', - 'repo.artifact.delete': '', - - 'repo_group.create': {'data': {}}, - 'repo_group.edit': {'old_data': {}}, - 'repo_group.edit.permissions': {}, - 'repo_group.delete': {'old_data': {}}, + "user.login.success": {"user_agent": ""}, + "user.login.failure": {"user_agent": ""}, + "user.logout": {"user_agent": ""}, + "user.register": {}, + "user.password.reset_request": {}, + "user.push": {"user_agent": "", "commit_ids": []}, + "user.pull": {"user_agent": ""}, + "user.create": {"data": {}}, + "user.delete": {"old_data": {}}, + "user.edit": {"old_data": {}}, + "user.edit.permissions": {}, + "user.edit.ip.add": {"ip": {}, "user": {}}, + "user.edit.ip.delete": {"ip": {}, "user": {}}, + "user.edit.token.add": {"token": {}, "user": {}}, + "user.edit.token.delete": {"token": {}, "user": {}}, + "user.edit.email.add": {"email": ""}, + "user.edit.email.delete": {"email": ""}, + "user.edit.ssh_key.add": {"token": {}, "user": {}}, + "user.edit.ssh_key.delete": {"token": {}, "user": {}}, + "user.edit.password_reset.enabled": {}, + "user.edit.password_reset.disabled": {}, + "user_group.create": {"data": {}}, + "user_group.delete": {"old_data": {}}, + "user_group.edit": {"old_data": {}}, + "user_group.edit.permissions": {}, + "user_group.edit.member.add": {"user": {}}, + "user_group.edit.member.delete": {"user": {}}, + "repo.create": {"data": {}}, + "repo.fork": {"data": {}}, + "repo.edit": {"old_data": {}}, + "repo.edit.permissions": {}, + "repo.edit.permissions.branch": {}, + "repo.archive": {"old_data": {}}, + "repo.delete": {"old_data": {}}, + "repo.archive.download": {"user_agent": "", "archive_name": "", "archive_spec": "", "archive_cached": ""}, + "repo.permissions.branch_rule.create": {}, + "repo.permissions.branch_rule.edit": {}, + "repo.permissions.branch_rule.delete": {}, + "repo.pull_request.create": "", + "repo.pull_request.edit": "", + "repo.pull_request.delete": "", + "repo.pull_request.close": "", + "repo.pull_request.merge": "", + "repo.pull_request.vote": "", + "repo.pull_request.comment.create": "", + "repo.pull_request.comment.edit": "", + "repo.pull_request.comment.delete": "", + "repo.pull_request.reviewer.add": "", + "repo.pull_request.reviewer.delete": "", + "repo.pull_request.observer.add": "", + "repo.pull_request.observer.delete": "", + "repo.commit.strip": {"commit_id": ""}, + "repo.commit.comment.create": {"data": {}}, + "repo.commit.comment.delete": {"data": {}}, + "repo.commit.comment.edit": {"data": {}}, + "repo.commit.vote": "", + "repo.artifact.add": "", + "repo.artifact.delete": "", + "repo_group.create": {"data": {}}, + "repo_group.edit": {"old_data": {}}, + "repo_group.edit.permissions": {}, + "repo_group.delete": {"old_data": {}}, } ACTIONS = ACTIONS_V1 -SOURCE_WEB = 'source_web' -SOURCE_API = 'source_api' +SOURCE_WEB = "source_web" +SOURCE_API = "source_api" class UserWrap(object): @@ -132,19 +120,18 @@ class RepoWrap(object): self.repo_name = repo_name -def _store_log(action_name, action_data, user_id, username, user_data, - ip_address, repository_id, repository_name): +def _store_log(action_name, action_data, user_id, username, user_data, ip_address, repository_id, repository_name): user_log = UserLog() user_log.version = UserLog.VERSION_2 user_log.action = action_name - user_log.action_data = action_data or JsonRaw('{}') + user_log.action_data = action_data or JsonRaw("{}") user_log.user_ip = ip_address user_log.user_id = user_id user_log.username = username - user_log.user_data = user_data or JsonRaw('{}') + user_log.user_data = user_data or JsonRaw("{}") user_log.repository_id = repository_id user_log.repository_name = repository_name @@ -156,26 +143,25 @@ def _store_log(action_name, action_data, user_id, username, user_data, def store_web(*args, **kwargs): action_data = {} - org_action_data = kwargs.pop('action_data', {}) + org_action_data = kwargs.pop("action_data", {}) action_data.update(org_action_data) - action_data['source'] = SOURCE_WEB - kwargs['action_data'] = action_data + action_data["source"] = SOURCE_WEB + kwargs["action_data"] = action_data return store(*args, **kwargs) def store_api(*args, **kwargs): action_data = {} - org_action_data = kwargs.pop('action_data', {}) + org_action_data = kwargs.pop("action_data", {}) action_data.update(org_action_data) - action_data['source'] = SOURCE_API - kwargs['action_data'] = action_data + action_data["source"] = SOURCE_API + kwargs["action_data"] = action_data return store(*args, **kwargs) -def store(action, user, action_data=None, user_data=None, ip_addr=None, - repo=None, sa_session=None, commit=False): +def store(action, user, action_data=None, user_data=None, ip_addr=None, repo=None, sa_session=None, commit=False): """ Audit logger for various actions made by users, typically this results in a call such:: @@ -218,24 +204,23 @@ def store(action, user, action_data=None, user_data=None, ip_addr=None, action_spec = ACTIONS.get(action, None) if action_spec is None: - raise ValueError(f'Action `{action}` is not supported') + raise ValueError(f"Action `{action}` is not supported") if not sa_session: sa_session = meta.Session() try: - username = getattr(user, 'username', None) + username = getattr(user, "username", None) if not username: pass - user_id = getattr(user, 'user_id', None) + user_id = getattr(user, "user_id", None) if not user_id: # maybe we have username ? Try to figure user_id from username if username: - user_id = getattr( - User.get_by_username(username), 'user_id', None) + user_id = getattr(User.get_by_username(username), "user_id", None) - ip_addr = ip_addr or getattr(user, 'ip_addr', None) + ip_addr = ip_addr or getattr(user, "ip_addr", None) if not ip_addr: pass @@ -243,23 +228,21 @@ def store(action, user, action_data=None, user_data=None, ip_addr=None, # try to get this from the auth user if isinstance(user, AuthUser): user_data = { - 'username': user.username, - 'email': user.email, + "username": user.username, + "email": user.email, } - repository_name = getattr(repo, 'repo_name', None) - repository_id = getattr(repo, 'repo_id', None) + repository_name = getattr(repo, "repo_name", None) + repository_id = getattr(repo, "repo_id", None) if not repository_id: # maybe we have repo_name ? Try to figure repo_id from repo_name if repository_name: - repository_id = getattr( - Repository.get_by_repo_name(repository_name), 'repo_id', None) + repository_id = getattr(Repository.get_by_repo_name(repository_name), "repo_id", None) action_name = safe_str(action) ip_address = safe_str(ip_addr) with sa_session.no_autoflush: - user_log = _store_log( action_name=action_name, action_data=action_data or {}, @@ -268,36 +251,38 @@ def store(action, user, action_data=None, user_data=None, ip_addr=None, user_data=user_data or {}, ip_address=ip_address, repository_id=repository_id, - repository_name=repository_name + repository_name=repository_name, ) sa_session.add(user_log) if commit: sa_session.commit() - entry_id = user_log.entry_id or '' + entry_id = user_log.entry_id or "" update_user_last_activity(sa_session, user_id) if commit: sa_session.commit() - log.info('AUDIT[%s]: Logging action: `%s` by user:id:%s[%s] ip:%s', - entry_id, action_name, user_id, username, ip_address, - extra={"entry_id": entry_id, "action": action_name, - "user_id": user_id, "ip": ip_address}) + log.info( + "AUDIT[%s]: Logging action: `%s` by user:id:%s[%s] ip:%s", + entry_id, + action_name, + user_id, + username, + ip_address, + extra={"entry_id": entry_id, "action": action_name, "user_id": user_id, "ip": ip_address}, + ) except Exception: - log.exception('AUDIT: failed to store audit log') + log.exception("AUDIT: failed to store audit log") def update_user_last_activity(sa_session, user_id): _last_activity = datetime.datetime.now() try: - sa_session.query(User).filter(User.user_id == user_id).update( - {"last_activity": _last_activity}) - log.debug( - 'updated user `%s` last activity to:%s', user_id, _last_activity) + sa_session.query(User).filter(User.user_id == user_id).update({"last_activity": _last_activity}) + log.debug("updated user `%s` last activity to:%s", user_id, _last_activity) except Exception: log.exception("Failed last activity update for user_id: %s", user_id) sa_session.rollback() - diff --git a/rhodecode/lib/auth.py b/rhodecode/lib/auth.py index 3a2fe245..94661097 100644 --- a/rhodecode/lib/auth.py +++ b/rhodecode/lib/auth.py @@ -43,11 +43,21 @@ from rhodecode.model import meta from rhodecode.model.meta import Session from rhodecode.model.user import UserModel from rhodecode.model.db import ( - false, User, Repository, Permission, UserToPerm, UserGroupToPerm, UserGroupMember, - UserIpMap, UserApiKeys, RepoGroup, UserGroup, UserNotice) + false, + User, + Repository, + Permission, + UserToPerm, + UserGroupToPerm, + UserGroupMember, + UserIpMap, + UserApiKeys, + RepoGroup, + UserGroup, + UserNotice, +) from rhodecode.lib import rc_cache -from rhodecode.lib.utils import ( - get_repo_slug, get_repo_group_slug, get_user_group_slug) +from rhodecode.lib.utils import get_repo_slug, get_repo_group_slug, get_user_group_slug from rhodecode.lib.type_utils import aslist from rhodecode.lib.hash_utils import sha1, sha256, md5 from rhodecode.lib.str_utils import ascii_bytes, safe_str, safe_int, safe_bytes @@ -69,24 +79,24 @@ class PasswordGenerator(object): of alphabet passwd_gen.gen_password(8, passwd_gen.ALPHABETS_BIG_SMALL) """ - ALPHABETS_NUM = r'''1234567890''' - ALPHABETS_SMALL = r'''qwertyuiopasdfghjklzxcvbnm''' - ALPHABETS_BIG = r'''QWERTYUIOPASDFGHJKLZXCVBNM''' - ALPHABETS_SPECIAL = r'''`-=[]\;',./~!@#$%^&*()_+{}|:"<>?''' - ALPHABETS_FULL = ALPHABETS_BIG + ALPHABETS_SMALL \ - + ALPHABETS_NUM + ALPHABETS_SPECIAL + + ALPHABETS_NUM = r"""1234567890""" + ALPHABETS_SMALL = r"""qwertyuiopasdfghjklzxcvbnm""" + ALPHABETS_BIG = r"""QWERTYUIOPASDFGHJKLZXCVBNM""" + ALPHABETS_SPECIAL = r"""`-=[]\;',./~!@#$%^&*()_+{}|:"<>?""" + ALPHABETS_FULL = ALPHABETS_BIG + ALPHABETS_SMALL + ALPHABETS_NUM + ALPHABETS_SPECIAL ALPHABETS_ALPHANUM = ALPHABETS_BIG + ALPHABETS_SMALL + ALPHABETS_NUM ALPHABETS_BIG_SMALL = ALPHABETS_BIG + ALPHABETS_SMALL ALPHABETS_ALPHANUM_BIG = ALPHABETS_BIG + ALPHABETS_NUM ALPHABETS_ALPHANUM_SMALL = ALPHABETS_SMALL + ALPHABETS_NUM - def __init__(self, passwd=''): + def __init__(self, passwd=""): self.passwd = passwd def gen_password(self, length, type_=None): if type_ is None: type_ = self.ALPHABETS_FULL - self.passwd = ''.join([random.choice(type_) for _ in range(length)]) + self.passwd = "".join([random.choice(type_) for _ in range(length)]) return self.passwd @@ -133,7 +143,7 @@ class _RhodeCodeCryptoBase(object): class _RhodeCodeCryptoBCrypt(_RhodeCodeCryptoBase): - ENC_PREF = ('$2a$10', '$2b$10') + ENC_PREF = ("$2a$10", "$2b$10") def hash_create(self, str_): self._assert_bytes(str_) @@ -182,8 +192,7 @@ class _RhodeCodeCryptoBCrypt(_RhodeCodeCryptoBase): except ValueError as e: # we're having a invalid salt here probably, we should not crash # just return with False as it would be a wrong password. - log.debug('Failed to check password hash using bcrypt %s', - safe_str(e)) + log.debug("Failed to check password hash using bcrypt %s", safe_str(e)) return False @@ -193,7 +202,8 @@ class _RhodeCodeCryptoSha256(_RhodeCodeCryptoBase): Legacy CryptoBackend used in OLD versions on Windows. Now it's just here to Migrate passwords to new backend bcrypt """ - ENC_PREF = '_' + + ENC_PREF = "_" def hash_create(self, str_): self._assert_bytes(str_) @@ -211,7 +221,7 @@ class _RhodeCodeCryptoSha256(_RhodeCodeCryptoBase): class _RhodeCodeCryptoTest(_RhodeCodeCryptoBase): - ENC_PREF = '_' + ENC_PREF = "_" def hash_create(self, str_): self._assert_bytes(str_) @@ -284,23 +294,22 @@ def get_came_from(request): _req = request path = _req.path - if 'auth_token' in _req.GET: + if "auth_token" in _req.GET: # sanitize the request and remove auth_token for redirection - _req.GET.pop('auth_token') + _req.GET.pop("auth_token") qs = _req.query_string if qs: - path += '?' + qs + path += "?" + qs return path class CookieStoreWrapper(object): - def __init__(self, cookie_store): self.cookie_store = cookie_store def __repr__(self): - return f'CookieStore<{self.cookie_store}>' + return f"CookieStore<{self.cookie_store}>" def get(self, key, other=None): if isinstance(self.cookie_store, dict): @@ -309,38 +318,37 @@ class CookieStoreWrapper(object): return self.cookie_store.__dict__.get(key, other) -def _cached_perms_data(user_id, scope, user_is_admin, - user_inherit_default_permissions, explicit, algo, - calculate_super_admin): - +def _cached_perms_data( + user_id, scope, user_is_admin, user_inherit_default_permissions, explicit, algo, calculate_super_admin +): permissions = PermissionCalculator( - user_id, scope, user_is_admin, user_inherit_default_permissions, - explicit, algo, calculate_super_admin) + user_id, scope, user_is_admin, user_inherit_default_permissions, explicit, algo, calculate_super_admin + ) return permissions.calculate() class PermOrigin(object): - SUPER_ADMIN = 'superadmin' - ARCHIVED = 'archived' + SUPER_ADMIN = "superadmin" + ARCHIVED = "archived" - REPO_USER = 'user:%s' - REPO_USERGROUP = 'usergroup:%s' - REPO_OWNER = 'repo.owner' - REPO_DEFAULT = 'repo.default' - REPO_DEFAULT_NO_INHERIT = 'repo.default.no.inherit' - REPO_PRIVATE = 'repo.private' + REPO_USER = "user:%s" + REPO_USERGROUP = "usergroup:%s" + REPO_OWNER = "repo.owner" + REPO_DEFAULT = "repo.default" + REPO_DEFAULT_NO_INHERIT = "repo.default.no.inherit" + REPO_PRIVATE = "repo.private" - REPOGROUP_USER = 'user:%s' - REPOGROUP_USERGROUP = 'usergroup:%s' - REPOGROUP_OWNER = 'group.owner' - REPOGROUP_DEFAULT = 'group.default' - REPOGROUP_DEFAULT_NO_INHERIT = 'group.default.no.inherit' + REPOGROUP_USER = "user:%s" + REPOGROUP_USERGROUP = "usergroup:%s" + REPOGROUP_OWNER = "group.owner" + REPOGROUP_DEFAULT = "group.default" + REPOGROUP_DEFAULT_NO_INHERIT = "group.default.no.inherit" - USERGROUP_USER = 'user:%s' - USERGROUP_USERGROUP = 'usergroup:%s' - USERGROUP_OWNER = 'usergroup.owner' - USERGROUP_DEFAULT = 'usergroup.default' - USERGROUP_DEFAULT_NO_INHERIT = 'usergroup.default.no.inherit' + USERGROUP_USER = "user:%s" + USERGROUP_USERGROUP = "usergroup:%s" + USERGROUP_OWNER = "usergroup.owner" + USERGROUP_DEFAULT = "usergroup.default" + USERGROUP_DEFAULT_NO_INHERIT = "usergroup.default.no.inherit" class PermOriginDict(dict): @@ -392,6 +400,7 @@ class BranchPermOriginDict(dict): >>> perms.perm_origin_stack {'resource': {'*pattern': [('read', 'default'), ('write', 'admin')]}} """ + def __init__(self, *args, **kw): dict.__init__(self, *args, **kw) self.perm_origin_stack = collections.OrderedDict() @@ -406,19 +415,22 @@ class BranchPermOriginDict(dict): (pattern_perm, origin) = pattern_perm_origin # we're passing in the dict, so we save the the stack for pattern, perm in list(pattern_perm.items()): - self.perm_origin_stack.setdefault(key, {})\ - .setdefault(pattern, []).append((perm, origin)) + self.perm_origin_stack.setdefault(key, {}).setdefault(pattern, []).append((perm, origin)) dict.__setitem__(self, key, pattern_perm) class PermissionCalculator(object): - def __init__( - self, user_id, scope, user_is_admin, - user_inherit_default_permissions, explicit, algo, - calculate_super_admin_as_user=False): - + self, + user_id, + scope, + user_is_admin, + user_inherit_default_permissions, + explicit, + algo, + calculate_super_admin_as_user=False, + ): self.user_id = user_id self.user_is_admin = user_is_admin self.inherit_default_permissions = user_inherit_default_permissions @@ -427,9 +439,9 @@ class PermissionCalculator(object): self.calculate_super_admin_as_user = calculate_super_admin_as_user scope = scope or {} - self.scope_repo_id = scope.get('repo_id') - self.scope_repo_group_id = scope.get('repo_group_id') - self.scope_user_group_id = scope.get('user_group_id') + self.scope_repo_id = scope.get("repo_id") + self.scope_repo_group_id = scope.get("repo_group_id") + self.scope_user_group_id = scope.get("user_group_id") self.default_user_id = User.get_default_user(cache=True).user_id @@ -439,18 +451,18 @@ class PermissionCalculator(object): self.permissions_repository_branches = BranchPermOriginDict() self.permissions_global = set() - self.default_repo_perms = Permission.get_default_repo_perms( - self.default_user_id, self.scope_repo_id) + self.default_repo_perms = Permission.get_default_repo_perms(self.default_user_id, self.scope_repo_id) self.default_repo_groups_perms = Permission.get_default_group_perms( - self.default_user_id, self.scope_repo_group_id) - self.default_user_group_perms = \ - Permission.get_default_user_group_perms( - self.default_user_id, self.scope_user_group_id) + self.default_user_id, self.scope_repo_group_id + ) + self.default_user_group_perms = Permission.get_default_user_group_perms( + self.default_user_id, self.scope_user_group_id + ) # default branch perms - self.default_branch_repo_perms = \ - Permission.get_default_repo_branch_perms( - self.default_user_id, self.scope_repo_id) + self.default_branch_repo_perms = Permission.get_default_repo_branch_perms( + self.default_user_id, self.scope_repo_id + ) def calculate(self): if self.user_is_admin and not self.calculate_super_admin_as_user: @@ -470,41 +482,40 @@ class PermissionCalculator(object): super-admin user have all default rights for repositories and groups set to admin """ - self.permissions_global.add('hg.admin') - self.permissions_global.add('hg.create.write_on_repogroup.true') + self.permissions_global.add("hg.admin") + self.permissions_global.add("hg.create.write_on_repogroup.true") # repositories for perm in self.default_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name obj_id = perm.UserRepoToPerm.repository.repo_id archived = perm.UserRepoToPerm.repository.archived - p = 'repository.admin' + p = "repository.admin" self.permissions_repositories[r_k] = p, PermOrigin.SUPER_ADMIN, obj_id # special case for archived repositories, which we block still even for # super admins if archived: - p = 'repository.read' + p = "repository.read" self.permissions_repositories[r_k] = p, PermOrigin.ARCHIVED, obj_id # repository groups for perm in self.default_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name obj_id = perm.UserRepoGroupToPerm.group.group_id - p = 'group.admin' + p = "group.admin" self.permissions_repository_groups[rg_k] = p, PermOrigin.SUPER_ADMIN, obj_id # user groups for perm in self.default_user_group_perms: u_k = perm.UserUserGroupToPerm.user_group.users_group_name obj_id = perm.UserUserGroupToPerm.user_group.users_group_id - p = 'usergroup.admin' + p = "usergroup.admin" self.permissions_user_groups[u_k] = p, PermOrigin.SUPER_ADMIN, obj_id # branch permissions # since super-admin also can have custom rule permissions # we *always* need to calculate those inherited from default, and also explicit - self._calculate_default_permissions_repository_branches( - user_inherit_object_permissions=False) + self._calculate_default_permissions_repository_branches(user_inherit_object_permissions=False) self._calculate_repository_branch_permissions() return self._permission_structure() @@ -513,16 +524,18 @@ class PermissionCalculator(object): """ global permissions taken from the default user """ - default_global_perms = UserToPerm.query()\ - .filter(UserToPerm.user_id == self.default_user_id)\ + default_global_perms = ( + UserToPerm.query() + .filter(UserToPerm.user_id == self.default_user_id) .options(joinedload(UserToPerm.permission)) + ) for perm in default_global_perms: self.permissions_global.add(perm.permission.permission_name) if self.user_is_admin: - self.permissions_global.add('hg.admin') - self.permissions_global.add('hg.create.write_on_repogroup.true') + self.permissions_global.add("hg.admin") + self.permissions_global.add("hg.create.write_on_repogroup.true") def _calculate_global_permissions(self): """ @@ -540,30 +553,39 @@ class PermissionCalculator(object): # this is in sync with User.DEFAULT_USER_PERMISSIONS definitions from rhodecode.model.permission import PermissionModel - _configurable = frozenset([ - PermissionModel.FORKING_DISABLED, PermissionModel.FORKING_ENABLED, - 'hg.create.none', 'hg.create.repository', - 'hg.usergroup.create.false', 'hg.usergroup.create.true', - 'hg.repogroup.create.false', 'hg.repogroup.create.true', - 'hg.create.write_on_repogroup.false', 'hg.create.write_on_repogroup.true', - 'hg.inherit_default_perms.false', 'hg.inherit_default_perms.true' - ]) + _configurable = frozenset( + [ + PermissionModel.FORKING_DISABLED, + PermissionModel.FORKING_ENABLED, + "hg.create.none", + "hg.create.repository", + "hg.usergroup.create.false", + "hg.usergroup.create.true", + "hg.repogroup.create.false", + "hg.repogroup.create.true", + "hg.create.write_on_repogroup.false", + "hg.create.write_on_repogroup.true", + "hg.inherit_default_perms.false", + "hg.inherit_default_perms.true", + ] + ) # USER GROUPS comes first user group global permissions - user_perms_from_users_groups = Session().query(UserGroupToPerm)\ - .options(joinedload(UserGroupToPerm.permission))\ - .join((UserGroupMember, UserGroupToPerm.users_group_id == - UserGroupMember.users_group_id))\ - .filter(UserGroupMember.user_id == self.user_id)\ - .order_by(UserGroupToPerm.users_group_id)\ + user_perms_from_users_groups = ( + Session() + .query(UserGroupToPerm) + .options(joinedload(UserGroupToPerm.permission)) + .join((UserGroupMember, UserGroupToPerm.users_group_id == UserGroupMember.users_group_id)) + .filter(UserGroupMember.user_id == self.user_id) + .order_by(UserGroupToPerm.users_group_id) .all() + ) # need to group here by groups since user can be in more than # one group, so we get all groups _explicit_grouped_perms = [ - [x, list(y)] for x, y in - itertools.groupby(user_perms_from_users_groups, - lambda _x: _x.users_group)] + [x, list(y)] for x, y in itertools.groupby(user_perms_from_users_groups, lambda _x: _x.users_group) + ] for gr, perms in _explicit_grouped_perms: # since user can be in multiple groups iterate over them and @@ -575,21 +597,23 @@ class PermissionCalculator(object): # NEED TO IGNORE all previously set configurable permissions # and replace them with explicitly set from this user # group permissions - self.permissions_global = self.permissions_global.difference( - _configurable) + self.permissions_global = self.permissions_global.difference(_configurable) for perm in perms: self.permissions_global.add(perm.permission.permission_name) # user explicit global permissions - user_perms = Session().query(UserToPerm)\ - .options(joinedload(UserToPerm.permission))\ - .filter(UserToPerm.user_id == self.user_id).all() + user_perms = ( + Session() + .query(UserToPerm) + .options(joinedload(UserToPerm.permission)) + .filter(UserToPerm.user_id == self.user_id) + .all() + ) if not self.inherit_default_permissions: # NEED TO IGNORE all configurable permissions and # replace them with explicitly set from this user permissions - self.permissions_global = self.permissions_global.difference( - _configurable) + self.permissions_global = self.permissions_global.difference(_configurable) for perm in user_perms: self.permissions_global.add(perm.permission.permission_name) @@ -606,25 +630,24 @@ class PermissionCalculator(object): # default user we set him to .none so only explicit # permissions work if not user_inherit_object_permissions: - p = 'repository.none' + p = "repository.none" o = PermOrigin.REPO_DEFAULT_NO_INHERIT self.permissions_repositories[r_k] = p, o, obj_id - if perm.Repository.private and not ( - perm.Repository.user_id == self.user_id): + if perm.Repository.private and not (perm.Repository.user_id == self.user_id): # disable defaults for private repos, - p = 'repository.none' + p = "repository.none" o = PermOrigin.REPO_PRIVATE self.permissions_repositories[r_k] = p, o, obj_id elif perm.Repository.user_id == self.user_id: # set admin if owner - p = 'repository.admin' + p = "repository.admin" o = PermOrigin.REPO_OWNER self.permissions_repositories[r_k] = p, o, obj_id if self.user_is_admin: - p = 'repository.admin' + p = "repository.admin" o = PermOrigin.SUPER_ADMIN self.permissions_repositories[r_k] = p, o, obj_id @@ -632,14 +655,13 @@ class PermissionCalculator(object): # permissions to read if archived: current_perm = self.permissions_repositories[r_k] - if current_perm in ['repository.write', 'repository.admin']: - p = 'repository.read' + if current_perm in ["repository.write", "repository.admin"]: + p = "repository.read" o = PermOrigin.ARCHIVED self.permissions_repositories[r_k] = p, o, obj_id def _calculate_default_permissions_repository_branches(self, user_inherit_object_permissions): for perm in self.default_branch_repo_perms: - r_k = perm.UserRepoToPerm.repository.repo_name p = perm.Permission.permission_name pattern = perm.UserToRepoBranchPermission.branch_pattern @@ -649,7 +671,7 @@ class PermissionCalculator(object): cur_perm = self.permissions_repository_branches.get(r_k) if cur_perm: cur_perm = cur_perm[pattern] - cur_perm = cur_perm or 'branch.none' + cur_perm = cur_perm or "branch.none" p = self._choose_permission(p, cur_perm) @@ -668,18 +690,18 @@ class PermissionCalculator(object): # if we decide this user isn't inheriting permissions from default # user we set him to .none so only explicit permissions work if not user_inherit_object_permissions: - p = 'group.none' + p = "group.none" o = PermOrigin.REPOGROUP_DEFAULT_NO_INHERIT self.permissions_repository_groups[rg_k] = p, o, obj_id if perm.RepoGroup.user_id == self.user_id: # set admin if owner - p = 'group.admin' + p = "group.admin" o = PermOrigin.REPOGROUP_OWNER self.permissions_repository_groups[rg_k] = p, o, obj_id if self.user_is_admin: - p = 'group.admin' + p = "group.admin" o = PermOrigin.SUPER_ADMIN self.permissions_repository_groups[rg_k] = p, o, obj_id @@ -694,18 +716,18 @@ class PermissionCalculator(object): # if we decide this user isn't inheriting permissions from default # user we set him to .none so only explicit permissions work if not user_inherit_object_permissions: - p = 'usergroup.none' + p = "usergroup.none" o = PermOrigin.USERGROUP_DEFAULT_NO_INHERIT self.permissions_user_groups[u_k] = p, o, obj_id if perm.UserGroup.user_id == self.user_id: # set admin if owner - p = 'usergroup.admin' + p = "usergroup.admin" o = PermOrigin.USERGROUP_OWNER self.permissions_user_groups[u_k] = p, o, obj_id if self.user_is_admin: - p = 'usergroup.admin' + p = "usergroup.admin" o = PermOrigin.SUPER_ADMIN self.permissions_user_groups[u_k] = p, o, obj_id @@ -726,21 +748,16 @@ class PermissionCalculator(object): .false is more important """ - user_inherit_object_permissions = ( - 'hg.inherit_default_perms.false' not in self.permissions_global) + user_inherit_object_permissions = "hg.inherit_default_perms.false" not in self.permissions_global # default permissions inherited from `default` user permissions - self._calculate_default_permissions_repositories( - user_inherit_object_permissions) + self._calculate_default_permissions_repositories(user_inherit_object_permissions) - self._calculate_default_permissions_repository_branches( - user_inherit_object_permissions) + self._calculate_default_permissions_repository_branches(user_inherit_object_permissions) - self._calculate_default_permissions_repository_groups( - user_inherit_object_permissions) + self._calculate_default_permissions_repository_groups(user_inherit_object_permissions) - self._calculate_default_permissions_user_groups( - user_inherit_object_permissions) + self._calculate_default_permissions_user_groups(user_inherit_object_permissions) def _calculate_repository_permissions(self): """ @@ -752,9 +769,9 @@ class PermissionCalculator(object): """ # user group for repositories permissions - user_repo_perms_from_user_group = Permission\ - .get_default_repo_perms_from_user_group( - self.user_id, self.scope_repo_id) + user_repo_perms_from_user_group = Permission.get_default_repo_perms_from_user_group( + self.user_id, self.scope_repo_id + ) multiple_counter = collections.defaultdict(int) for perm in user_repo_perms_from_user_group: @@ -762,8 +779,7 @@ class PermissionCalculator(object): obj_id = perm.UserGroupRepoToPerm.repository.repo_id multiple_counter[r_k] += 1 p = perm.Permission.permission_name - o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm\ - .users_group.users_group_name + o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm.users_group.users_group_name if multiple_counter[r_k] > 1: cur_perm = self.permissions_repositories[r_k] @@ -773,19 +789,18 @@ class PermissionCalculator(object): if perm.Repository.user_id == self.user_id: # set admin if owner - p = 'repository.admin' + p = "repository.admin" o = PermOrigin.REPO_OWNER self.permissions_repositories[r_k] = p, o, obj_id if self.user_is_admin: - p = 'repository.admin' + p = "repository.admin" o = PermOrigin.SUPER_ADMIN self.permissions_repositories[r_k] = p, o, obj_id # user explicit permissions for repositories, overrides any specified # by the group permission - user_repo_perms = Permission.get_default_repo_perms( - self.user_id, self.scope_repo_id) + user_repo_perms = Permission.get_default_repo_perms(self.user_id, self.scope_repo_id) for perm in user_repo_perms: r_k = perm.UserRepoToPerm.repository.repo_name obj_id = perm.UserRepoToPerm.repository.repo_id @@ -794,20 +809,19 @@ class PermissionCalculator(object): o = PermOrigin.REPO_USER % perm.UserRepoToPerm.user.username if not self.explicit: - cur_perm = self.permissions_repositories.get( - r_k, 'repository.none') + cur_perm = self.permissions_repositories.get(r_k, "repository.none") p = self._choose_permission(p, cur_perm) self.permissions_repositories[r_k] = p, o, obj_id if perm.Repository.user_id == self.user_id: # set admin if owner - p = 'repository.admin' + p = "repository.admin" o = PermOrigin.REPO_OWNER self.permissions_repositories[r_k] = p, o, obj_id if self.user_is_admin: - p = 'repository.admin' + p = "repository.admin" o = PermOrigin.SUPER_ADMIN self.permissions_repositories[r_k] = p, o, obj_id @@ -815,24 +829,23 @@ class PermissionCalculator(object): # permissions to read if archived: current_perm = self.permissions_repositories[r_k] - if current_perm in ['repository.write', 'repository.admin']: - p = 'repository.read' + if current_perm in ["repository.write", "repository.admin"]: + p = "repository.read" o = PermOrigin.ARCHIVED self.permissions_repositories[r_k] = p, o, obj_id def _calculate_repository_branch_permissions(self): # user group for repositories permissions - user_repo_branch_perms_from_user_group = Permission\ - .get_default_repo_branch_perms_from_user_group( - self.user_id, self.scope_repo_id) + user_repo_branch_perms_from_user_group = Permission.get_default_repo_branch_perms_from_user_group( + self.user_id, self.scope_repo_id + ) multiple_counter = collections.defaultdict(int) for perm in user_repo_branch_perms_from_user_group: r_k = perm.UserGroupRepoToPerm.repository.repo_name p = perm.Permission.permission_name pattern = perm.UserGroupToRepoBranchPermission.branch_pattern - o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm\ - .users_group.users_group_name + o = PermOrigin.REPO_USERGROUP % perm.UserGroupRepoToPerm.users_group.users_group_name multiple_counter[r_k] += 1 if multiple_counter[r_k] > 1: @@ -843,11 +856,9 @@ class PermissionCalculator(object): # user explicit branch permissions for repositories, overrides # any specified by the group permission - user_repo_branch_perms = Permission.get_default_repo_branch_perms( - self.user_id, self.scope_repo_id) + user_repo_branch_perms = Permission.get_default_repo_branch_perms(self.user_id, self.scope_repo_id) for perm in user_repo_branch_perms: - r_k = perm.UserRepoToPerm.repository.repo_name p = perm.Permission.permission_name pattern = perm.UserToRepoBranchPermission.branch_pattern @@ -857,7 +868,7 @@ class PermissionCalculator(object): cur_perm = self.permissions_repository_branches.get(r_k) if cur_perm: cur_perm = cur_perm[pattern] - cur_perm = cur_perm or 'branch.none' + cur_perm = cur_perm or "branch.none" p = self._choose_permission(p, cur_perm) # NOTE(marcink): register all pattern/perm instances in this @@ -873,17 +884,16 @@ class PermissionCalculator(object): permission should be selected based on selected method. """ # user group for repo groups permissions - user_repo_group_perms_from_user_group = Permission\ - .get_default_group_perms_from_user_group( - self.user_id, self.scope_repo_group_id) + user_repo_group_perms_from_user_group = Permission.get_default_group_perms_from_user_group( + self.user_id, self.scope_repo_group_id + ) multiple_counter = collections.defaultdict(int) for perm in user_repo_group_perms_from_user_group: rg_k = perm.UserGroupRepoGroupToPerm.group.group_name obj_id = perm.UserGroupRepoGroupToPerm.group.group_id multiple_counter[rg_k] += 1 - o = PermOrigin.REPOGROUP_USERGROUP % perm.UserGroupRepoGroupToPerm\ - .users_group.users_group_name + o = PermOrigin.REPOGROUP_USERGROUP % perm.UserGroupRepoGroupToPerm.users_group.users_group_name p = perm.Permission.permission_name if multiple_counter[rg_k] > 1: @@ -893,39 +903,37 @@ class PermissionCalculator(object): if perm.RepoGroup.user_id == self.user_id: # set admin if owner, even for member of other user group - p = 'group.admin' + p = "group.admin" o = PermOrigin.REPOGROUP_OWNER self.permissions_repository_groups[rg_k] = p, o, obj_id if self.user_is_admin: - p = 'group.admin' + p = "group.admin" o = PermOrigin.SUPER_ADMIN self.permissions_repository_groups[rg_k] = p, o, obj_id # user explicit permissions for repository groups - user_repo_groups_perms = Permission.get_default_group_perms( - self.user_id, self.scope_repo_group_id) + user_repo_groups_perms = Permission.get_default_group_perms(self.user_id, self.scope_repo_group_id) for perm in user_repo_groups_perms: rg_k = perm.UserRepoGroupToPerm.group.group_name obj_id = perm.UserRepoGroupToPerm.group.group_id - o = PermOrigin.REPOGROUP_USER % perm.UserRepoGroupToPerm\ - .user.username + o = PermOrigin.REPOGROUP_USER % perm.UserRepoGroupToPerm.user.username p = perm.Permission.permission_name if not self.explicit: - cur_perm = self.permissions_repository_groups.get(rg_k, 'group.none') + cur_perm = self.permissions_repository_groups.get(rg_k, "group.none") p = self._choose_permission(p, cur_perm) self.permissions_repository_groups[rg_k] = p, o, obj_id if perm.RepoGroup.user_id == self.user_id: # set admin if owner - p = 'group.admin' + p = "group.admin" o = PermOrigin.REPOGROUP_OWNER self.permissions_repository_groups[rg_k] = p, o, obj_id if self.user_is_admin: - p = 'group.admin' + p = "group.admin" o = PermOrigin.SUPER_ADMIN self.permissions_repository_groups[rg_k] = p, o, obj_id @@ -934,17 +942,16 @@ class PermissionCalculator(object): User group permissions for the current user. """ # user group for user group permissions - user_group_from_user_group = Permission\ - .get_default_user_group_perms_from_user_group( - self.user_id, self.scope_user_group_id) + user_group_from_user_group = Permission.get_default_user_group_perms_from_user_group( + self.user_id, self.scope_user_group_id + ) multiple_counter = collections.defaultdict(int) for perm in user_group_from_user_group: ug_k = perm.UserGroupUserGroupToPerm.target_user_group.users_group_name obj_id = perm.UserGroupUserGroupToPerm.target_user_group.users_group_id multiple_counter[ug_k] += 1 - o = PermOrigin.USERGROUP_USERGROUP % perm.UserGroupUserGroupToPerm\ - .user_group.users_group_name + o = PermOrigin.USERGROUP_USERGROUP % perm.UserGroupUserGroupToPerm.user_group.users_group_name p = perm.Permission.permission_name if multiple_counter[ug_k] > 1: @@ -955,61 +962,59 @@ class PermissionCalculator(object): if perm.UserGroup.user_id == self.user_id: # set admin if owner, even for member of other user group - p = 'usergroup.admin' + p = "usergroup.admin" o = PermOrigin.USERGROUP_OWNER self.permissions_user_groups[ug_k] = p, o, obj_id if self.user_is_admin: - p = 'usergroup.admin' + p = "usergroup.admin" o = PermOrigin.SUPER_ADMIN self.permissions_user_groups[ug_k] = p, o, obj_id # user explicit permission for user groups - user_user_groups_perms = Permission.get_default_user_group_perms( - self.user_id, self.scope_user_group_id) + user_user_groups_perms = Permission.get_default_user_group_perms(self.user_id, self.scope_user_group_id) for perm in user_user_groups_perms: ug_k = perm.UserUserGroupToPerm.user_group.users_group_name obj_id = perm.UserUserGroupToPerm.user_group.users_group_id - o = PermOrigin.USERGROUP_USER % perm.UserUserGroupToPerm\ - .user.username + o = PermOrigin.USERGROUP_USER % perm.UserUserGroupToPerm.user.username p = perm.Permission.permission_name if not self.explicit: - cur_perm = self.permissions_user_groups.get(ug_k, 'usergroup.none') + cur_perm = self.permissions_user_groups.get(ug_k, "usergroup.none") p = self._choose_permission(p, cur_perm) self.permissions_user_groups[ug_k] = p, o, obj_id if perm.UserGroup.user_id == self.user_id: # set admin if owner - p = 'usergroup.admin' + p = "usergroup.admin" o = PermOrigin.USERGROUP_OWNER self.permissions_user_groups[ug_k] = p, o, obj_id if self.user_is_admin: - p = 'usergroup.admin' + p = "usergroup.admin" o = PermOrigin.SUPER_ADMIN self.permissions_user_groups[ug_k] = p, o, obj_id def _choose_permission(self, new_perm, cur_perm): new_perm_val = Permission.PERM_WEIGHTS[new_perm] cur_perm_val = Permission.PERM_WEIGHTS[cur_perm] - if self.algo == 'higherwin': + if self.algo == "higherwin": if new_perm_val > cur_perm_val: return new_perm return cur_perm - elif self.algo == 'lowerwin': + elif self.algo == "lowerwin": if new_perm_val < cur_perm_val: return new_perm return cur_perm def _permission_structure(self): return { - 'global': self.permissions_global, - 'repositories': self.permissions_repositories, - 'repository_branches': self.permissions_repository_branches, - 'repositories_groups': self.permissions_repository_groups, - 'user_groups': self.permissions_user_groups, + "global": self.permissions_global, + "repositories": self.permissions_repositories, + "repository_branches": self.permissions_repository_branches, + "repositories_groups": self.permissions_repository_groups, + "user_groups": self.permissions_user_groups, } @@ -1019,21 +1024,20 @@ def allowed_auth_token_access(view_name, auth_token, whitelist=None): """ if not whitelist: from rhodecode import CONFIG - whitelist = aslist( - CONFIG.get('api_access_controllers_whitelist'), sep=',') + + whitelist = aslist(CONFIG.get("api_access_controllers_whitelist"), sep=",") # backward compat translation compat = { # old controller, new VIEW - 'ChangesetController:*': 'RepoCommitsView:*', - 'ChangesetController:changeset_patch': 'RepoCommitsView:repo_commit_patch', - 'ChangesetController:changeset_raw': 'RepoCommitsView:repo_commit_raw', - 'FilesController:raw': 'RepoCommitsView:repo_commit_raw', - 'FilesController:archivefile': 'RepoFilesView:repo_archivefile', - 'GistsController:*': 'GistView:*', + "ChangesetController:*": "RepoCommitsView:*", + "ChangesetController:changeset_patch": "RepoCommitsView:repo_commit_patch", + "ChangesetController:changeset_raw": "RepoCommitsView:repo_commit_raw", + "FilesController:raw": "RepoCommitsView:repo_commit_raw", + "FilesController:archivefile": "RepoFilesView:repo_archivefile", + "GistsController:*": "GistView:*", } - log.debug( - 'Allowed views for AUTH TOKEN access: %s', whitelist) + log.debug("Allowed views for AUTH TOKEN access: %s", whitelist) auth_token_access_valid = False for entry in whitelist: @@ -1042,9 +1046,9 @@ def allowed_auth_token_access(view_name, auth_token, whitelist=None): # translate from old Controllers to Pyramid Views entry = compat[entry] - if '@' in entry: + if "@" in entry: # specific AuthToken - entry, allowed_token = entry.split('@', 1) + entry, allowed_token = entry.split("@", 1) token_match = auth_token == allowed_token if fnmatch.fnmatch(view_name, entry) and token_match: @@ -1052,12 +1056,10 @@ def allowed_auth_token_access(view_name, auth_token, whitelist=None): break if auth_token_access_valid: - log.debug('view: `%s` matches entry in whitelist: %s', - view_name, whitelist) + log.debug("view: `%s` matches entry in whitelist: %s", view_name, whitelist) else: - msg = ('view: `%s` does *NOT* match any entry in whitelist: %s' - % (view_name, whitelist)) + msg = "view: `%s` does *NOT* match any entry in whitelist: %s" % (view_name, whitelist) if auth_token: # if we use auth token key and don't have access it's a warning log.warning(msg) @@ -1075,28 +1077,28 @@ class AuthUser(object): Then it fills all required information for such user. It also checks if anonymous access is enabled and if so, it returns default user as logged in """ + GLOBAL_PERMS = [x[0] for x in Permission.PERMS] - repo_read_perms = ['repository.read', 'repository.admin', 'repository.write'] - repo_group_read_perms = ['group.read', 'group.write', 'group.admin'] - user_group_read_perms = ['usergroup.read', 'usergroup.write', 'usergroup.admin'] + repo_read_perms = ["repository.read", "repository.admin", "repository.write"] + repo_group_read_perms = ["group.read", "group.write", "group.admin"] + user_group_read_perms = ["usergroup.read", "usergroup.write", "usergroup.admin"] def __init__(self, user_id=None, api_key=None, username=None, ip_addr=None): - self.user_id = user_id self._api_key = api_key self.api_key = None self.username = username self.ip_addr = ip_addr - self.name = '' - self.lastname = '' - self.first_name = '' - self.last_name = '' - self.email = '' + self.name = "" + self.lastname = "" + self.first_name = "" + self.last_name = "" + self.email = "" self.is_authenticated = False self.admin = False self.inherit_default_permissions = False - self.password = '' + self.password = "" self.anonymous_user = None # propagated on propagate_data self.propagate_data() @@ -1114,28 +1116,19 @@ class AuthUser(object): """ perms = self.get_perms(user=self, cache=None) - perms['repositories'] = { - k: v for k, v in list(perms['repositories'].items()) - if v != 'repository.none' + perms["repositories"] = {k: v for k, v in list(perms["repositories"].items()) if v != "repository.none"} + perms["repositories_groups"] = { + k: v for k, v in list(perms["repositories_groups"].items()) if v != "group.none" } - perms['repositories_groups'] = { - k: v for k, v in list(perms['repositories_groups'].items()) - if v != 'group.none' - } - perms['user_groups'] = { - k: v for k, v in list(perms['user_groups'].items()) - if v != 'usergroup.none' - } - perms['repository_branches'] = { - k: v for k, v in list(perms['repository_branches'].items()) - if v != 'branch.none' + perms["user_groups"] = {k: v for k, v in list(perms["user_groups"].items()) if v != "usergroup.none"} + perms["repository_branches"] = { + k: v for k, v in list(perms["repository_branches"].items()) if v != "branch.none" } return perms @LazyProperty def permissions_full_details(self): - return self.get_perms( - user=self, cache=None, calculate_super_admin=True) + return self.get_perms(user=self, cache=None, calculate_super_admin=True) def permissions_with_scope(self, scope): """ @@ -1146,14 +1139,14 @@ class AuthUser(object): :param scope: dict """ - if 'repo_name' in scope: - obj = Repository.get_by_repo_name(scope['repo_name']) + if "repo_name" in scope: + obj = Repository.get_by_repo_name(scope["repo_name"]) if obj: - scope['repo_id'] = obj.repo_id + scope["repo_id"] = obj.repo_id _scope = collections.OrderedDict() - _scope['repo_id'] = -1 - _scope['user_group_id'] = -1 - _scope['repo_group_id'] = -1 + _scope["repo_id"] = -1 + _scope["user_group_id"] = -1 + _scope["repo_group_id"] = -1 for k in sorted(scope.keys()): _scope[k] = scope[k] @@ -1171,52 +1164,50 @@ class AuthUser(object): Fills in user data and propagates values to this instance. Maps fetched user attributes to this class instance attributes """ - log.debug('AuthUser: starting data propagation for new potential user') + log.debug("AuthUser: starting data propagation for new potential user") user_model = UserModel() anon_user = self.anonymous_user = User.get_default_user(cache=True) is_user_loaded = False # lookup by userid if self.user_id is not None and self.user_id != anon_user.user_id: - log.debug('Trying Auth User lookup by USER ID: `%s`', self.user_id) + log.debug("Trying Auth User lookup by USER ID: `%s`", self.user_id) is_user_loaded = user_model.fill_data(self, user_id=self.user_id) # try go get user by api key elif self._api_key and self._api_key != anon_user.api_key: - log.debug('Trying Auth User lookup by API KEY: `...%s`', self._api_key[-4:]) + log.debug("Trying Auth User lookup by API KEY: `...%s`", self._api_key[-4:]) is_user_loaded = user_model.fill_data(self, api_key=self._api_key) # lookup by username elif self.username: - log.debug('Trying Auth User lookup by USER NAME: `%s`', self.username) + log.debug("Trying Auth User lookup by USER NAME: `%s`", self.username) is_user_loaded = user_model.fill_data(self, username=self.username) else: - log.debug('No data in %s that could been used to log in', self) + log.debug("No data in %s that could been used to log in", self) if not is_user_loaded: - log.debug( - 'Failed to load user. Fallback to default user %s', anon_user) + log.debug("Failed to load user. Fallback to default user %s", anon_user) # if we cannot authenticate user try anonymous if anon_user.active: - log.debug('default user is active, using it as a session user') + log.debug("default user is active, using it as a session user") user_model.fill_data(self, user_id=anon_user.user_id) # then we set this user is logged in self.is_authenticated = True else: - log.debug('default user is NOT active') + log.debug("default user is NOT active") # in case of disabled anonymous user we reset some of the # parameters so such user is "corrupted", skipping the fill_data - for attr in ['user_id', 'username', 'admin', 'active']: + for attr in ["user_id", "username", "admin", "active"]: setattr(self, attr, None) self.is_authenticated = False if not self.username: - self.username = 'None' + self.username = "None" - log.debug('AuthUser: propagated user is now %s', self) + log.debug("AuthUser: propagated user is now %s", self) - def get_perms(self, user, scope=None, explicit=True, algo='higherwin', - calculate_super_admin=False, cache=None): + def get_perms(self, user, scope=None, explicit=True, algo="higherwin", calculate_super_admin=False, cache=None): """ Fills user permission attribute with permissions taken from database works for permissions given for repositories, and for permissions that @@ -1242,8 +1233,7 @@ class AuthUser(object): # inheritance of global permissions like create repo/fork repo etc user_inherit_default_permissions = user.inherit_default_permissions - cache_seconds = safe_int( - rhodecode.CONFIG.get('rc_cache.cache_perms.expiration_time')) + cache_seconds = safe_int(rhodecode.CONFIG.get("rc_cache.cache_perms.expiration_time")) if cache is None: # let the backend cache decide @@ -1252,33 +1242,50 @@ class AuthUser(object): cache_on = cache log.debug( - 'Computing PERMISSION tree for user %s scope `%s` ' - 'with caching: %s[TTL: %ss]', user, scope, cache_on, cache_seconds or 0) + "Computing PERMISSION tree for user %s scope `%s` with caching: %s[TTL: %ss]", + user, + scope, + cache_on, + cache_seconds or 0, + ) - cache_namespace_uid = f'cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{user_id}' - region = rc_cache.get_or_create_region('cache_perms', cache_namespace_uid) + cache_namespace_uid = f"cache_user_auth.{rc_cache.PERMISSIONS_CACHE_VER}.{user_id}" + region = rc_cache.get_or_create_region("cache_perms", cache_namespace_uid) - @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, - condition=cache_on) - def compute_perm_tree(cache_name, cache_ver, - user_id, scope, user_is_admin,user_inherit_default_permissions, - explicit, algo, calculate_super_admin): + @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, condition=cache_on) + def compute_perm_tree( + cache_name, + cache_ver, + user_id, + scope, + user_is_admin, + user_inherit_default_permissions, + explicit, + algo, + calculate_super_admin, + ): return _cached_perms_data( - user_id, scope, user_is_admin, user_inherit_default_permissions, - explicit, algo, calculate_super_admin) + user_id, scope, user_is_admin, user_inherit_default_permissions, explicit, algo, calculate_super_admin + ) start = time.time() result = compute_perm_tree( - 'permissions', 'v1', user_id, scope, user_is_admin, - user_inherit_default_permissions, explicit, algo, - calculate_super_admin) + "permissions", + "v1", + user_id, + scope, + user_is_admin, + user_inherit_default_permissions, + explicit, + algo, + calculate_super_admin, + ) result_repr = [] for k in result: result_repr.append((k, len(result[k]))) total = time.time() - start - log.debug('PERMISSION tree for user %s computed in %.4fs: %s', - user, total, result_repr) + log.debug("PERMISSION tree for user %s computed in %.4fs: %s", user, total, result_repr) return result @@ -1299,33 +1306,27 @@ class AuthUser(object): """ Returns list of repositories you're an admin of """ - return [ - x[0] for x in list(self.permissions['repositories'].items()) - if x[1] == 'repository.admin'] + return [x[0] for x in list(self.permissions["repositories"].items()) if x[1] == "repository.admin"] @property def repository_groups_admin(self): """ Returns list of repository groups you're an admin of """ - return [ - x[0] for x in list(self.permissions['repositories_groups'].items()) - if x[1] == 'group.admin'] + return [x[0] for x in list(self.permissions["repositories_groups"].items()) if x[1] == "group.admin"] @property def user_groups_admin(self): """ Returns list of user groups you're an admin of """ - return [ - x[0] for x in list(self.permissions['user_groups'].items()) - if x[1] == 'usergroup.admin'] + return [x[0] for x in list(self.permissions["user_groups"].items()) if x[1] == "usergroup.admin"] def repo_acl_ids_from_stack(self, perms=None, prefix_filter=None, cache=False): if not perms: perms = AuthUser.repo_read_perms allowed_ids = [] - for k, stack_data in list(self.permissions['repositories'].perm_origin_stack.items()): + for k, stack_data in list(self.permissions["repositories"].perm_origin_stack.items()): perm, origin, obj_id = stack_data[-1] # last item is the current permission if prefix_filter and not k.startswith(prefix_filter): continue @@ -1340,35 +1341,34 @@ class AuthUser(object): display purposes, NOT IN ANY CASE for permission checks. """ from rhodecode.model.scm import RepoList + if not perms: perms = AuthUser.repo_read_perms if not isinstance(perms, list): - raise ValueError('perms parameter must be a list got {} instead'.format(perms)) + raise ValueError("perms parameter must be a list got {} instead".format(perms)) def _cached_repo_acl(perm_def, _name_filter): qry = Repository.query() if _name_filter: - ilike_expression = '%{}%'.format(_name_filter) - qry = qry.filter( - Repository.repo_name.ilike(ilike_expression)) + ilike_expression = "%{}%".format(_name_filter) + qry = qry.filter(Repository.repo_name.ilike(ilike_expression)) - return [x.repo_id for x in - RepoList(qry, perm_set=perm_def, extra_kwargs={'user': self})] + return [x.repo_id for x in RepoList(qry, perm_set=perm_def, extra_kwargs={"user": self})] - log.debug('Computing REPO ACL IDS user %s', self) + log.debug("Computing REPO ACL IDS user %s", self) - cache_namespace_uid = f'cache_user_repo_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{self.user_id}' - region = rc_cache.get_or_create_region('cache_perms', cache_namespace_uid) + cache_namespace_uid = f"cache_user_repo_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{self.user_id}" + region = rc_cache.get_or_create_region("cache_perms", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, condition=cache) def compute_repo_acl_ids(cache_ver, user_id, perm_def, _name_filter): return _cached_repo_acl(perm_def, _name_filter) start = time.time() - result = compute_repo_acl_ids('v1', self.user_id, perms, name_filter) + result = compute_repo_acl_ids("v1", self.user_id, perms, name_filter) total = time.time() - start - log.debug('REPO ACL IDS for user %s computed in %.4fs', self, total) + log.debug("REPO ACL IDS for user %s computed in %.4fs", self, total) return result @@ -1376,7 +1376,7 @@ class AuthUser(object): if not perms: perms = AuthUser.repo_group_read_perms allowed_ids = [] - for k, stack_data in list(self.permissions['repositories_groups'].perm_origin_stack.items()): + for k, stack_data in list(self.permissions["repositories_groups"].perm_origin_stack.items()): perm, origin, obj_id = stack_data[-1] # last item is the current permission if prefix_filter and not k.startswith(prefix_filter): continue @@ -1391,35 +1391,34 @@ class AuthUser(object): display purposes, NOT IN ANY CASE for permission checks. """ from rhodecode.model.scm import RepoGroupList + if not perms: perms = AuthUser.repo_group_read_perms if not isinstance(perms, list): - raise ValueError(f'perms parameter must be a list got {perms} instead') + raise ValueError(f"perms parameter must be a list got {perms} instead") def _cached_repo_group_acl(perm_def, _name_filter): qry = RepoGroup.query() if _name_filter: - ilike_expression = '%{}%'.format(_name_filter) - qry = qry.filter( - RepoGroup.group_name.ilike(ilike_expression)) + ilike_expression = "%{}%".format(_name_filter) + qry = qry.filter(RepoGroup.group_name.ilike(ilike_expression)) - return [x.group_id for x in - RepoGroupList(qry, perm_set=perm_def, extra_kwargs={'user': self})] + return [x.group_id for x in RepoGroupList(qry, perm_set=perm_def, extra_kwargs={"user": self})] - log.debug('Computing REPO GROUP ACL IDS user %s', self) + log.debug("Computing REPO GROUP ACL IDS user %s", self) - cache_namespace_uid = f'cache_user_repo_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{self.user_id}' - region = rc_cache.get_or_create_region('cache_perms', cache_namespace_uid) + cache_namespace_uid = f"cache_user_repo_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{self.user_id}" + region = rc_cache.get_or_create_region("cache_perms", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, condition=cache) def compute_repo_group_acl_ids(cache_ver, user_id, perm_def, _name_filter): return _cached_repo_group_acl(perm_def, _name_filter) start = time.time() - result = compute_repo_group_acl_ids('v1', self.user_id, perms, name_filter) + result = compute_repo_group_acl_ids("v1", self.user_id, perms, name_filter) total = time.time() - start - log.debug('REPO GROUP ACL IDS for user %s computed in %.4fs', self, total) + log.debug("REPO GROUP ACL IDS for user %s computed in %.4fs", self, total) return result @@ -1427,7 +1426,7 @@ class AuthUser(object): if not perms: perms = AuthUser.user_group_read_perms allowed_ids = [] - for k, stack_data in list(self.permissions['user_groups'].perm_origin_stack.items()): + for k, stack_data in list(self.permissions["user_groups"].perm_origin_stack.items()): perm, origin, obj_id = stack_data[-1] # last item is the current permission if perm in perms: allowed_ids.append(obj_id) @@ -1440,35 +1439,34 @@ class AuthUser(object): display purposes, NOT IN ANY CASE for permission checks. """ from rhodecode.model.scm import UserGroupList + if not perms: perms = AuthUser.user_group_read_perms if not isinstance(perms, list): - raise ValueError('perms parameter must be a list got {} instead'.format(perms)) + raise ValueError("perms parameter must be a list got {} instead".format(perms)) def _cached_user_group_acl(perm_def, _name_filter): qry = UserGroup.query() if _name_filter: - ilike_expression = '%{}%'.format(_name_filter) - qry = qry.filter( - UserGroup.users_group_name.ilike(ilike_expression)) + ilike_expression = "%{}%".format(_name_filter) + qry = qry.filter(UserGroup.users_group_name.ilike(ilike_expression)) - return [x.users_group_id for x in - UserGroupList(qry, perm_set=perm_def, extra_kwargs={'user': self})] + return [x.users_group_id for x in UserGroupList(qry, perm_set=perm_def, extra_kwargs={"user": self})] - log.debug('Computing USER GROUP ACL IDS user %s', self) + log.debug("Computing USER GROUP ACL IDS user %s", self) - cache_namespace_uid = f'cache_user_user_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{self.user_id}' - region = rc_cache.get_or_create_region('cache_perms', cache_namespace_uid) + cache_namespace_uid = f"cache_user_user_group_acl_ids.{rc_cache.PERMISSIONS_CACHE_VER}.{self.user_id}" + region = rc_cache.get_or_create_region("cache_perms", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid, condition=cache) def compute_user_group_acl_ids(cache_ver, user_id, perm_def, _name_filter): return _cached_user_group_acl(perm_def, _name_filter) start = time.time() - result = compute_user_group_acl_ids('v1', self.user_id, perms, name_filter) + result = compute_user_group_acl_ids("v1", self.user_id, perms, name_filter) total = time.time() - start - log.debug('USER GROUP ACL IDS for user %s computed in %.4fs', self, total) + log.debug("USER GROUP ACL IDS for user %s computed in %.4fs", self, total) return result @@ -1482,8 +1480,7 @@ class AuthUser(object): """ # check IP inherit = self.inherit_default_permissions - return AuthUser.check_ip_allowed(self.user_id, self.ip_addr, - inherit_from_default=inherit) + return AuthUser.check_ip_allowed(self.user_id, self.ip_addr, inherit_from_default=inherit) @property def personal_repo_group(self): @@ -1499,21 +1496,23 @@ class AuthUser(object): @classmethod def check_ip_allowed(cls, user_id, ip_addr, inherit_from_default): - allowed_ips = AuthUser.get_allowed_ips( - user_id, cache=True, inherit_from_default=inherit_from_default) + allowed_ips = AuthUser.get_allowed_ips(user_id, cache=True, inherit_from_default=inherit_from_default) if check_ip_access(source_ip=ip_addr, allowed_ips=allowed_ips): - log.debug('IP:%s for user %s is in range of %s', - ip_addr, user_id, allowed_ips) + log.debug("IP:%s for user %s is in range of %s", ip_addr, user_id, allowed_ips) return True else: - log.info('Access for IP:%s forbidden for user %s, ' - 'not in %s', ip_addr, user_id, allowed_ips, - extra={"ip": ip_addr, "user_id": user_id}) + log.info( + "Access for IP:%s forbidden for user %s, not in %s", + ip_addr, + user_id, + allowed_ips, + extra={"ip": ip_addr, "user_id": user_id}, + ) return False def get_branch_permissions(self, repo_name, perms=None): - perms = perms or self.permissions_with_scope({'repo_name': repo_name}) - branch_perms = perms.get('repository_branches', {}) + perms = perms or self.permissions_with_scope({"repo_name": repo_name}) + branch_perms = perms.get("repository_branches", {}) if not branch_perms: return {} repo_branch_perms = branch_perms.get(repo_name) @@ -1525,7 +1524,7 @@ class AuthUser(object): the rules match in order, we return the matching permissions """ - rule = default_perm = '' + rule = default_perm = "" repo_branch_perms = self.get_branch_permissions(repo_name=repo_name) if not repo_branch_perms: @@ -1534,38 +1533,38 @@ class AuthUser(object): # now calculate the permissions for pattern, branch_perm in list(repo_branch_perms.items()): if fnmatch.fnmatch(branch_name, pattern): - rule = '`{}`=>{}'.format(pattern, branch_perm) + rule = "`{}`=>{}".format(pattern, branch_perm) return rule, branch_perm return rule, default_perm def get_notice_messages(self): - - notice_level = 'notice-error' + notice_level = "notice-error" notice_messages = [] if self.is_default: return [], notice_level - notices = UserNotice.query()\ - .filter(UserNotice.user_id == self.user_id)\ - .filter(UserNotice.notice_read == false())\ + notices = ( + UserNotice.query() + .filter(UserNotice.user_id == self.user_id) + .filter(UserNotice.notice_read == false()) .all() + ) try: for entry in notices: - msg = { - 'msg_id': entry.user_notice_id, - 'level': entry.notification_level, - 'subject': entry.notice_subject, - 'body': entry.notice_body, + "msg_id": entry.user_notice_id, + "level": entry.notification_level, + "subject": entry.notice_subject, + "body": entry.notice_body, } notice_messages.append(msg) - log.debug('Got user %s %s messages', self, len(notice_messages)) + log.debug("Got user %s %s messages", self, len(notice_messages)) - levels = [x['level'] for x in notice_messages] - notice_level = 'notice-error' if 'error' in levels else 'notice-warning' + levels = [x["level"] for x in notice_messages] + notice_level = "notice-error" if "error" in levels else "notice-warning" except Exception: pass @@ -1580,14 +1579,14 @@ class AuthUser(object): def get_cookie_store(self): return { - 'username': self.username, - 'password': md5(safe_bytes(self.password or '')), - 'user_id': self.user_id, - 'is_authenticated': self.is_authenticated + "username": self.username, + "password": md5(safe_bytes(self.password or "")), + "user_id": self.user_id, + "is_authenticated": self.is_authenticated, } @classmethod - def repr_user(cls, user_id=0, username='ANONYMOUS', ip='0.0.0.0', is_authenticated=False): + def repr_user(cls, user_id=0, username="ANONYMOUS", ip="0.0.0.0", is_authenticated=False): tmpl = "" return tmpl.format(user_id, username, ip, is_authenticated) @@ -1599,9 +1598,9 @@ class AuthUser(object): :param cls: :param cookie_store: """ - user_id = cookie_store.get('user_id') - username = cookie_store.get('username') - api_key = cookie_store.get('api_key') + user_id = cookie_store.get("user_id") + username = cookie_store.get("username") + api_key = cookie_store.get("api_key") return AuthUser(user_id, api_key, username) @classmethod @@ -1612,8 +1611,7 @@ class AuthUser(object): def_user_id = User.get_default_user(cache=True).user_id default_ips = UserIpMap.query().filter(UserIpMap.user_id == def_user_id) if cache: - default_ips = default_ips.options( - FromCache("sql_cache_short", "get_user_ips_default")) + default_ips = default_ips.options(FromCache("sql_cache_short", "get_user_ips_default")) # populate from default user for ip in default_ips: @@ -1631,8 +1629,7 @@ class AuthUser(object): if user_id: user_ips = UserIpMap.query().filter(UserIpMap.user_id == user_id) if cache: - user_ips = user_ips.options( - FromCache("sql_cache_short", f"get_user_ips_{user_id}")) + user_ips = user_ips.options(FromCache("sql_cache_short", f"get_user_ips_{user_id}")) for ip in user_ips: try: @@ -1641,7 +1638,7 @@ class AuthUser(object): # since we use heavy caching sometimes it happens that we get # deleted objects here, we just skip them pass - return _set or {ip for ip in ['0.0.0.0/0', '::/0']} + return _set or {ip for ip in ["0.0.0.0/0", "::/0"]} def set_available_permissions(settings): @@ -1654,15 +1651,14 @@ def set_available_permissions(settings): :param settings: current pyramid registry.settings """ - log.debug('auth: getting information about all available permissions') + log.debug("auth: getting information about all available permissions") try: sa = meta.Session all_perms = sa.query(Permission).all() - settings.setdefault('available_permissions', - [x.permission_name for x in all_perms]) - log.debug('auth: set available permissions') + settings.setdefault("available_permissions", [x.permission_name for x in all_perms]) + log.debug("auth: set available permissions") except Exception: - log.exception('Failed to fetch permissions from the database.') + log.exception("Failed to fetch permissions from the database.") raise @@ -1682,13 +1678,14 @@ def get_csrf_token(session, force_new=False, save_if_missing=True): if (csrf_token_key not in session and save_if_missing) or force_new: token = sha1(ascii_bytes(str(random.getrandbits(128)))) session[csrf_token_key] = token - if hasattr(session, 'save'): + if hasattr(session, "save"): session.save() return session.get(csrf_token_key) def get_request(perm_class_instance): from rhodecode.lib.pyramid_utils import get_current_request + pyramid_request = get_current_request() return pyramid_request @@ -1707,7 +1704,8 @@ class CSRFRequired(object): For use with the ``secure_form`` helper functions. """ - def __init__(self, token=csrf_token_key, header='X-CSRF-Token', except_methods=None): + + def __init__(self, token=csrf_token_key, header="X-CSRF-Token", except_methods=None): self.token = token self.header = header self.except_methods = except_methods or [] @@ -1738,19 +1736,20 @@ class CSRFRequired(object): del request.POST[self.token] return func(*fargs, **fkwargs) else: - reason = 'token-missing' + reason = "token-missing" supplied_token = self._get_csrf(request) if supplied_token and cur_token != supplied_token: - reason = 'token-mismatch [%s:%s]' % ( - cur_token or ''[:6], supplied_token or ''[:6]) + reason = "token-mismatch [%s:%s]" % (cur_token or ""[:6], supplied_token or ""[:6]) - csrf_message = \ - ("Cross-site request forgery detected, request denied. See " - "http://en.wikipedia.org/wiki/Cross-site_request_forgery for " - "more information.") - log.warning('Cross-site request forgery detected, request %r DENIED: %s ' - 'REMOTE_ADDR:%s, HEADERS:%s' % ( - request, reason, request.remote_addr, request.headers)) + csrf_message = ( + "Cross-site request forgery detected, request denied. See " + "http://en.wikipedia.org/wiki/Cross-site_request_forgery for " + "more information." + ) + log.warning( + "Cross-site request forgery detected, request %r DENIED: %s " + "REMOTE_ADDR:%s, HEADERS:%s" % (request, reason, request.remote_addr, request.headers) + ) raise HTTPForbidden(explanation=csrf_message) @@ -1763,13 +1762,15 @@ class LoginRequired(object): :param auth_token_access: if enabled this checks only for valid auth token and grants access based on valid token """ + def __init__(self, auth_token_access=None): self.auth_token_access = auth_token_access if self.auth_token_access: valid_type = set(auth_token_access).intersection(set(UserApiKeys.ROLES)) if not valid_type: - raise ValueError('auth_token_access must be on of {}, got {}'.format( - UserApiKeys.ROLES, auth_token_access)) + raise ValueError( + "auth_token_access must be on of {}, got {}".format(UserApiKeys.ROLES, auth_token_access) + ) def __call__(self, func): return get_cython_compat_decorator(self.__wrapper, func) @@ -1779,18 +1780,18 @@ class LoginRequired(object): def __wrapper(self, func, *fargs, **fkwargs): from rhodecode.lib import helpers as h + cls = fargs[0] user = cls._rhodecode_user request = cls.request or self._get_request() _ = request.translate loc = "%s:%s" % (cls.__class__.__name__, func.__name__) - log.debug('Starting login restriction checks for user: %s', user) + log.debug("Starting login restriction checks for user: %s", user) # check if our IP is allowed ip_access_valid = True if not user.ip_allowed: - h.flash(h.literal(_('IP {} not allowed'.format(user.ip_addr))), - category='warning') + h.flash(h.literal(_("IP {} not allowed".format(user.ip_addr))), category="warning") ip_access_valid = False # we used stored token that is extract from GET or URL param (if any) @@ -1803,12 +1804,11 @@ class LoginRequired(object): # since this location is allowed by @LoginRequired decorator it's our # only whitelist whitelist = [loc] - auth_token_access_valid = allowed_auth_token_access( - loc, whitelist=whitelist, auth_token=_auth_token) + auth_token_access_valid = allowed_auth_token_access(loc, whitelist=whitelist, auth_token=_auth_token) # explicit controller is enabled or API is in our whitelist if auth_token_access_valid: - log.debug('Checking AUTH TOKEN access for %s', cls) + log.debug("Checking AUTH TOKEN access for %s", cls) db_user = user.get_instance() if db_user: @@ -1816,17 +1816,15 @@ class LoginRequired(object): roles = self.auth_token_access else: roles = [UserApiKeys.ROLE_HTTP] - log.debug('AUTH TOKEN: checking auth for user %s and roles %s', - db_user, roles) - token_match = db_user.authenticate_by_token( - _auth_token, roles=roles) + log.debug("AUTH TOKEN: checking auth for user %s and roles %s", db_user, roles) + token_match = db_user.authenticate_by_token(_auth_token, roles=roles) else: - log.debug('Unable to fetch db instance for auth user: %s', user) + log.debug("Unable to fetch db instance for auth user: %s", user) token_match = False if _auth_token and token_match: auth_token_access_valid = True - log.debug('AUTH TOKEN ****%s is VALID', _auth_token[-4:]) + log.debug("AUTH TOKEN ****%s is VALID", _auth_token[-4:]) else: auth_token_access_valid = False if not _auth_token: @@ -1834,27 +1832,27 @@ class LoginRequired(object): else: log.warning("AUTH TOKEN ****%s *NOT* valid", _auth_token[-4:]) - log.debug('Checking if %s is authenticated @ %s', user.username, loc) - reason = 'RHODECODE_AUTH' if user.is_authenticated \ - else 'AUTH_TOKEN_AUTH' + log.debug("Checking if %s is authenticated @ %s", user.username, loc) + reason = "RHODECODE_AUTH" if user.is_authenticated else "AUTH_TOKEN_AUTH" - if ip_access_valid and ( - user.is_authenticated or auth_token_access_valid): - log.info('user %s authenticating with:%s IS authenticated on func %s', - user, reason, loc) + if ip_access_valid and (user.is_authenticated or auth_token_access_valid): + log.info("user %s authenticating with:%s IS authenticated on func %s", user, reason, loc) return func(*fargs, **fkwargs) else: log.warning( - 'user %s authenticating with:%s NOT authenticated on ' - 'func: %s: IP_ACCESS:%s AUTH_TOKEN_ACCESS:%s', - user, reason, loc, ip_access_valid, auth_token_access_valid) + "user %s authenticating with:%s NOT authenticated on func: %s: IP_ACCESS:%s AUTH_TOKEN_ACCESS:%s", + user, + reason, + loc, + ip_access_valid, + auth_token_access_valid, + ) # we preserve the get PARAM came_from = get_came_from(request) - log.debug('redirecting to login page with %s', came_from) - raise HTTPFound( - h.route_path('login', _query={'came_from': came_from})) + log.debug("redirecting to login page with %s", came_from) + raise HTTPFound(h.route_path("login", _query={"came_from": came_from})) class NotAnonymous(object): @@ -1871,21 +1869,19 @@ class NotAnonymous(object): def __wrapper(self, func, *fargs, **fkwargs): import rhodecode.lib.helpers as h + cls = fargs[0] self.user = cls._rhodecode_user request = cls.request or self._get_request() _ = request.translate - log.debug('Checking if user is not anonymous @%s', cls) + log.debug("Checking if user is not anonymous @%s", cls) anonymous = self.user.username == User.DEFAULT_USER if anonymous: came_from = get_came_from(request) - h.flash(_('You need to be a registered user to ' - 'perform this action'), - category='warning') - raise HTTPFound( - h.route_path('login', _query={'came_from': came_from})) + h.flash(_("You need to be a registered user to perform this action"), category="warning") + raise HTTPFound(h.route_path("login", _query={"came_from": came_from})) else: return func(*fargs, **fkwargs) @@ -1912,24 +1908,22 @@ class PermsDecorator(object): self.request = request _ = request.translate - log.debug('checking %s permissions %s for %s %s', - self.__class__.__name__, self.required_perms, cls, _user) + log.debug("checking %s permissions %s for %s %s", self.__class__.__name__, self.required_perms, cls, _user) if self.check_permissions(_user): - log.debug('Permission granted for %s %s', cls, _user) + log.debug("Permission granted for %s %s", cls, _user) return func(*fargs, **fkwargs) else: - log.debug('Permission denied for %s %s', cls, _user) + log.debug("Permission denied for %s %s", cls, _user) anonymous = _user.username == User.DEFAULT_USER if anonymous: import rhodecode.lib.helpers as h + came_from = get_came_from(self._get_request()) - h.flash(_('You need to be signed in to view this page'), - category='warning') - raise HTTPFound( - h.route_path('login', _query={'came_from': came_from})) + h.flash(_("You need to be signed in to view this page"), category="warning") + raise HTTPFound(h.route_path("login", _query={"came_from": came_from})) else: # redirect with 404 to prevent resource discovery @@ -1937,8 +1931,7 @@ class PermsDecorator(object): def check_permissions(self, user): """Dummy function for overriding""" - raise NotImplementedError( - 'You have to write this function in child class') + raise NotImplementedError("You have to write this function in child class") class HasPermissionAllDecorator(PermsDecorator): @@ -1949,7 +1942,7 @@ class HasPermissionAllDecorator(PermsDecorator): def check_permissions(self, user): perms = user.permissions_with_scope({}) - if self.required_perms.issubset(perms['global']): + if self.required_perms.issubset(perms["global"]): return True return False @@ -1962,7 +1955,7 @@ class HasPermissionAnyDecorator(PermsDecorator): def check_permissions(self, user): perms = user.permissions_with_scope({}) - if self.required_perms.intersection(perms['global']): + if self.required_perms.intersection(perms["global"]): return True return False @@ -1972,6 +1965,7 @@ class HasRepoPermissionAllDecorator(PermsDecorator): Checks for access permission for all given predicates for specific repository. All of them have to be meet in order to fulfill the request """ + def _get_repo_name(self): _request = self.request or self._get_request() return get_repo_slug(_request) @@ -1981,13 +1975,11 @@ class HasRepoPermissionAllDecorator(PermsDecorator): repo_name = self._get_repo_name() try: - user_perms = {perms['repositories'][repo_name]} + user_perms = {perms["repositories"][repo_name]} except KeyError: - log.debug('cannot locate repo with name: `%s` in permissions defs', - repo_name) + log.debug("cannot locate repo with name: `%s` in permissions defs", repo_name) return False - log.debug('checking `%s` permissions for repo `%s`', - user_perms, repo_name) + log.debug("checking `%s` permissions for repo `%s`", user_perms, repo_name) if self.required_perms.issubset(user_perms): return True return False @@ -1998,6 +1990,7 @@ class HasRepoPermissionAnyDecorator(PermsDecorator): Checks for access permission for any of given predicates for specific repository. In order to fulfill the request any of predicates must be meet """ + def _get_repo_name(self): _request = self.request or self._get_request() return get_repo_slug(_request) @@ -2007,15 +2000,12 @@ class HasRepoPermissionAnyDecorator(PermsDecorator): repo_name = self._get_repo_name() try: - user_perms = {perms['repositories'][repo_name]} + user_perms = {perms["repositories"][repo_name]} except KeyError: - log.debug( - 'cannot locate repo with name: `%s` in permissions defs', - repo_name) + log.debug("cannot locate repo with name: `%s` in permissions defs", repo_name) return False - log.debug('checking `%s` permissions for repo `%s`', - user_perms, repo_name) + log.debug("checking `%s` permissions for repo `%s`", user_perms, repo_name) if self.required_perms.intersection(user_perms): return True return False @@ -2027,6 +2017,7 @@ class HasRepoGroupPermissionAllDecorator(PermsDecorator): repository group. All of them have to be meet in order to fulfill the request """ + def _get_repo_group_name(self): _request = self.request or self._get_request() return get_repo_group_slug(_request) @@ -2035,15 +2026,12 @@ class HasRepoGroupPermissionAllDecorator(PermsDecorator): perms = user.permissions group_name = self._get_repo_group_name() try: - user_perms = {perms['repositories_groups'][group_name]} + user_perms = {perms["repositories_groups"][group_name]} except KeyError: - log.debug( - 'cannot locate repo group with name: `%s` in permissions defs', - group_name) + log.debug("cannot locate repo group with name: `%s` in permissions defs", group_name) return False - log.debug('checking `%s` permissions for repo group `%s`', - user_perms, group_name) + log.debug("checking `%s` permissions for repo group `%s`", user_perms, group_name) if self.required_perms.issubset(user_perms): return True return False @@ -2055,6 +2043,7 @@ class HasRepoGroupPermissionAnyDecorator(PermsDecorator): repository group. In order to fulfill the request any of predicates must be met """ + def _get_repo_group_name(self): _request = self.request or self._get_request() return get_repo_group_slug(_request) @@ -2064,15 +2053,12 @@ class HasRepoGroupPermissionAnyDecorator(PermsDecorator): group_name = self._get_repo_group_name() try: - user_perms = {perms['repositories_groups'][group_name]} + user_perms = {perms["repositories_groups"][group_name]} except KeyError: - log.debug( - 'cannot locate repo group with name: `%s` in permissions defs', - group_name) + log.debug("cannot locate repo group with name: `%s` in permissions defs", group_name) return False - log.debug('checking `%s` permissions for repo group `%s`', - user_perms, group_name) + log.debug("checking `%s` permissions for repo group `%s`", user_perms, group_name) if self.required_perms.intersection(user_perms): return True return False @@ -2083,6 +2069,7 @@ class HasUserGroupPermissionAllDecorator(PermsDecorator): Checks for access permission for all given predicates for specific user group. All of them have to be meet in order to fulfill the request """ + def _get_user_group_name(self): _request = self.request or self._get_request() return get_user_group_slug(_request) @@ -2091,7 +2078,7 @@ class HasUserGroupPermissionAllDecorator(PermsDecorator): perms = user.permissions group_name = self._get_user_group_name() try: - user_perms = {perms['user_groups'][group_name]} + user_perms = {perms["user_groups"][group_name]} except KeyError: return False @@ -2105,6 +2092,7 @@ class HasUserGroupPermissionAnyDecorator(PermsDecorator): Checks for access permission for any of given predicates for specific user group. In order to fulfill the request any of predicates must be meet """ + def _get_user_group_name(self): _request = self.request or self._get_request() return get_user_group_slug(_request) @@ -2113,7 +2101,7 @@ class HasUserGroupPermissionAnyDecorator(PermsDecorator): perms = user.permissions group_name = self._get_user_group_name() try: - user_perms = {perms['user_groups'][group_name]} + user_perms = {perms["user_groups"][group_name]} except KeyError: return False @@ -2134,45 +2122,43 @@ class PermsFunction(object): def __bool__(self): import inspect + frame = inspect.currentframe() stack_trace = traceback.format_stack(frame) - log.error('Checking bool value on a class instance of perm ' - 'function is not allowed: %s', ''.join(stack_trace)) + log.error("Checking bool value on a class instance of perm function is not allowed: %s", "".join(stack_trace)) # rather than throwing errors, here we always return False so if by # accident someone checks truth for just an instance it will always end # up in returning False return False + __nonzero__ = __bool__ - def __call__(self, check_location='', user=None): + def __call__(self, check_location="", user=None): if not user: - log.debug('Using user attribute from global request') + log.debug("Using user attribute from global request") request = self._get_request() user = request.user # init auth user if not already given if not isinstance(user, AuthUser): - log.debug('Wrapping user %s into AuthUser', user) + log.debug("Wrapping user %s into AuthUser", user) user = AuthUser(user.user_id) cls_name = self.__class__.__name__ check_scope = self._get_check_scope(cls_name) - check_location = check_location or 'unspecified location' + check_location = check_location or "unspecified location" - log.debug('checking cls:%s %s usr:%s %s @ %s', cls_name, - self.required_perms, user, check_scope, check_location) + log.debug("checking cls:%s %s usr:%s %s @ %s", cls_name, self.required_perms, user, check_scope, check_location) if not user: - log.warning('Empty user given for permission check') + log.warning("Empty user given for permission check") return False if self.check_permissions(user): - log.debug('Permission to repo:`%s` GRANTED for user:`%s` @ %s', - check_scope, user, check_location) + log.debug("Permission to repo:`%s` GRANTED for user:`%s` @ %s", check_scope, user, check_location) return True else: - log.debug('Permission to repo:`%s` DENIED for user:`%s` @ %s', - check_scope, user, check_location) + log.debug("Permission to repo:`%s` DENIED for user:`%s` @ %s", check_scope, user, check_location) return False def _get_request(self): @@ -2180,25 +2166,25 @@ class PermsFunction(object): def _get_check_scope(self, cls_name): return { - 'HasPermissionAll': 'GLOBAL', - 'HasPermissionAny': 'GLOBAL', - 'HasRepoPermissionAll': 'repo:%s' % self.repo_name, - 'HasRepoPermissionAny': 'repo:%s' % self.repo_name, - 'HasRepoGroupPermissionAll': 'repo_group:%s' % self.repo_group_name, - 'HasRepoGroupPermissionAny': 'repo_group:%s' % self.repo_group_name, - 'HasUserGroupPermissionAll': 'user_group:%s' % self.user_group_name, - 'HasUserGroupPermissionAny': 'user_group:%s' % self.user_group_name, - }.get(cls_name, '?:%s' % cls_name) + "HasPermissionAll": "GLOBAL", + "HasPermissionAny": "GLOBAL", + "HasRepoPermissionAll": "repo:%s" % self.repo_name, + "HasRepoPermissionAny": "repo:%s" % self.repo_name, + "HasRepoGroupPermissionAll": "repo_group:%s" % self.repo_group_name, + "HasRepoGroupPermissionAny": "repo_group:%s" % self.repo_group_name, + "HasUserGroupPermissionAll": "user_group:%s" % self.user_group_name, + "HasUserGroupPermissionAny": "user_group:%s" % self.user_group_name, + }.get(cls_name, "?:%s" % cls_name) def check_permissions(self, user): """Dummy function for overriding""" - raise Exception('You have to write this function in child class') + raise Exception("You have to write this function in child class") class HasPermissionAll(PermsFunction): def check_permissions(self, user): perms = user.permissions_with_scope({}) - if self.required_perms.issubset(perms.get('global')): + if self.required_perms.issubset(perms.get("global")): return True return False @@ -2206,13 +2192,13 @@ class HasPermissionAll(PermsFunction): class HasPermissionAny(PermsFunction): def check_permissions(self, user): perms = user.permissions_with_scope({}) - if self.required_perms.intersection(perms.get('global')): + if self.required_perms.intersection(perms.get("global")): return True return False class HasRepoPermissionAll(PermsFunction): - def __call__(self, repo_name=None, check_location='', user=None): + def __call__(self, repo_name=None, check_location="", user=None): self.repo_name = repo_name return super(HasRepoPermissionAll, self).__call__(check_location, user) @@ -2226,7 +2212,7 @@ class HasRepoPermissionAll(PermsFunction): self.repo_name = self._get_repo_name() perms = user.permissions try: - user_perms = {perms['repositories'][self.repo_name]} + user_perms = {perms["repositories"][self.repo_name]} except KeyError: return False if self.required_perms.issubset(user_perms): @@ -2235,7 +2221,7 @@ class HasRepoPermissionAll(PermsFunction): class HasRepoPermissionAny(PermsFunction): - def __call__(self, repo_name=None, check_location='', user=None): + def __call__(self, repo_name=None, check_location="", user=None): self.repo_name = repo_name return super(HasRepoPermissionAny, self).__call__(check_location, user) @@ -2249,7 +2235,7 @@ class HasRepoPermissionAny(PermsFunction): self.repo_name = self._get_repo_name() perms = user.permissions try: - user_perms = {perms['repositories'][self.repo_name]} + user_perms = {perms["repositories"][self.repo_name]} except KeyError: return False if self.required_perms.intersection(user_perms): @@ -2258,15 +2244,14 @@ class HasRepoPermissionAny(PermsFunction): class HasRepoGroupPermissionAny(PermsFunction): - - def __call__(self, group_name=None, check_location='', user=None): + def __call__(self, group_name=None, check_location="", user=None): self.repo_group_name = group_name return super(HasRepoGroupPermissionAny, self).__call__(check_location, user) def check_permissions(self, user): perms = user.permissions try: - user_perms = {perms['repositories_groups'][self.repo_group_name]} + user_perms = {perms["repositories_groups"][self.repo_group_name]} except KeyError: return False if self.required_perms.intersection(user_perms): @@ -2275,14 +2260,14 @@ class HasRepoGroupPermissionAny(PermsFunction): class HasRepoGroupPermissionAll(PermsFunction): - def __call__(self, group_name=None, check_location='', user=None): + def __call__(self, group_name=None, check_location="", user=None): self.repo_group_name = group_name return super(HasRepoGroupPermissionAll, self).__call__(check_location, user) def check_permissions(self, user): perms = user.permissions try: - user_perms = {perms['repositories_groups'][self.repo_group_name]} + user_perms = {perms["repositories_groups"][self.repo_group_name]} except KeyError: return False if self.required_perms.issubset(user_perms): @@ -2291,14 +2276,14 @@ class HasRepoGroupPermissionAll(PermsFunction): class HasUserGroupPermissionAny(PermsFunction): - def __call__(self, user_group_name=None, check_location='', user=None): + def __call__(self, user_group_name=None, check_location="", user=None): self.user_group_name = user_group_name return super(HasUserGroupPermissionAny, self).__call__(check_location, user) def check_permissions(self, user): perms = user.permissions try: - user_perms = {perms['user_groups'][self.user_group_name]} + user_perms = {perms["user_groups"][self.user_group_name]} except KeyError: return False if self.required_perms.intersection(user_perms): @@ -2307,14 +2292,14 @@ class HasUserGroupPermissionAny(PermsFunction): class HasUserGroupPermissionAll(PermsFunction): - def __call__(self, user_group_name=None, check_location='', user=None): + def __call__(self, user_group_name=None, check_location="", user=None): self.user_group_name = user_group_name return super(HasUserGroupPermissionAll, self).__call__(check_location, user) def check_permissions(self, user): perms = user.permissions try: - user_perms = {perms['user_groups'][self.user_group_name]} + user_perms = {perms["user_groups"][self.user_group_name]} except KeyError: return False if self.required_perms.issubset(user_perms): @@ -2330,30 +2315,28 @@ class HasPermissionAnyMiddleware(object): def __call__(self, auth_user, repo_name): # # repo_name MUST be unicode, since we handle keys in permission # # dict by unicode - #TODO: verify + # TODO: verify # repo_name = safe_str(repo_name) log.debug( - 'Checking VCS protocol permissions %s for user:%s repo:`%s`', - self.required_perms, auth_user, repo_name) + "Checking VCS protocol permissions %s for user:%s repo:`%s`", self.required_perms, auth_user, repo_name + ) if self.check_permissions(auth_user, repo_name): - log.debug('Permission to repo:`%s` GRANTED for user:%s @ %s', - repo_name, auth_user, 'PermissionMiddleware') + log.debug("Permission to repo:`%s` GRANTED for user:%s @ %s", repo_name, auth_user, "PermissionMiddleware") return True else: - log.debug('Permission to repo:`%s` DENIED for user:%s @ %s', - repo_name, auth_user, 'PermissionMiddleware') + log.debug("Permission to repo:`%s` DENIED for user:%s @ %s", repo_name, auth_user, "PermissionMiddleware") return False def check_permissions(self, user, repo_name): - perms = user.permissions_with_scope({'repo_name': repo_name}) + perms = user.permissions_with_scope({"repo_name": repo_name}) try: - user_perms = {perms['repositories'][repo_name]} + user_perms = {perms["repositories"][repo_name]} except Exception: - log.exception('Error while accessing user permissions') + log.exception("Error while accessing user permissions") return False if self.required_perms.intersection(user_perms): @@ -2366,43 +2349,37 @@ class _BaseApiPerm(object): def __init__(self, *perms): self.required_perms = set(perms) - def __call__(self, check_location=None, user=None, repo_name=None, - group_name=None, user_group_name=None): + def __call__(self, check_location=None, user=None, repo_name=None, group_name=None, user_group_name=None): cls_name = self.__class__.__name__ - check_scope = 'global:%s' % (self.required_perms,) + check_scope = "global:%s" % (self.required_perms,) if repo_name: - check_scope += ', repo_name:%s' % (repo_name,) + check_scope += ", repo_name:%s" % (repo_name,) if group_name: - check_scope += ', repo_group_name:%s' % (group_name,) + check_scope += ", repo_group_name:%s" % (group_name,) if user_group_name: - check_scope += ', user_group_name:%s' % (user_group_name,) + check_scope += ", user_group_name:%s" % (user_group_name,) - log.debug('checking cls:%s %s %s @ %s', - cls_name, self.required_perms, check_scope, check_location) + log.debug("checking cls:%s %s %s @ %s", cls_name, self.required_perms, check_scope, check_location) if not user: - log.debug('Empty User passed into arguments') + log.debug("Empty User passed into arguments") return False # process user if not isinstance(user, AuthUser): user = AuthUser(user.user_id) if not check_location: - check_location = 'unspecified' - if self.check_permissions(user.permissions, repo_name, group_name, - user_group_name): - log.debug('Permission to repo:`%s` GRANTED for user:`%s` @ %s', - check_scope, user, check_location) + check_location = "unspecified" + if self.check_permissions(user.permissions, repo_name, group_name, user_group_name): + log.debug("Permission to repo:`%s` GRANTED for user:`%s` @ %s", check_scope, user, check_location) return True else: - log.debug('Permission to repo:`%s` DENIED for user:`%s` @ %s', - check_scope, user, check_location) + log.debug("Permission to repo:`%s` DENIED for user:`%s` @ %s", check_scope, user, check_location) return False - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): """ implement in child class should return True if permissions are ok, False otherwise @@ -2414,26 +2391,23 @@ class _BaseApiPerm(object): class HasPermissionAllApi(_BaseApiPerm): - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): - if self.required_perms.issubset(perm_defs.get('global')): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): + if self.required_perms.issubset(perm_defs.get("global")): return True return False class HasPermissionAnyApi(_BaseApiPerm): - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): - if self.required_perms.intersection(perm_defs.get('global')): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): + if self.required_perms.intersection(perm_defs.get("global")): return True return False class HasRepoPermissionAllApi(_BaseApiPerm): - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): try: - _user_perms = {perm_defs['repositories'][repo_name]} + _user_perms = {perm_defs["repositories"][repo_name]} except KeyError: log.warning(traceback.format_exc()) return False @@ -2443,10 +2417,9 @@ class HasRepoPermissionAllApi(_BaseApiPerm): class HasRepoPermissionAnyApi(_BaseApiPerm): - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): try: - _user_perms = {perm_defs['repositories'][repo_name]} + _user_perms = {perm_defs["repositories"][repo_name]} except KeyError: log.warning(traceback.format_exc()) return False @@ -2456,10 +2429,9 @@ class HasRepoPermissionAnyApi(_BaseApiPerm): class HasRepoGroupPermissionAnyApi(_BaseApiPerm): - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): try: - _user_perms = {perm_defs['repositories_groups'][group_name]} + _user_perms = {perm_defs["repositories_groups"][group_name]} except KeyError: log.warning(traceback.format_exc()) return False @@ -2469,10 +2441,9 @@ class HasRepoGroupPermissionAnyApi(_BaseApiPerm): class HasRepoGroupPermissionAllApi(_BaseApiPerm): - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): try: - _user_perms = {perm_defs['repositories_groups'][group_name]} + _user_perms = {perm_defs["repositories_groups"][group_name]} except KeyError: log.warning(traceback.format_exc()) return False @@ -2482,10 +2453,9 @@ class HasRepoGroupPermissionAllApi(_BaseApiPerm): class HasUserGroupPermissionAnyApi(_BaseApiPerm): - def check_permissions(self, perm_defs, repo_name=None, group_name=None, - user_group_name=None): + def check_permissions(self, perm_defs, repo_name=None, group_name=None, user_group_name=None): try: - _user_perms = {perm_defs['user_groups'][user_group_name]} + _user_perms = {perm_defs["user_groups"][user_group_name]} except KeyError: log.warning(traceback.format_exc()) return False @@ -2501,16 +2471,16 @@ def check_ip_access(source_ip, allowed_ips=None): :param source_ip: :param allowed_ips: list of allowed ips together with mask """ - log.debug('checking if ip:%s is subnet of %s', source_ip, allowed_ips) + log.debug("checking if ip:%s is subnet of %s", source_ip, allowed_ips) source_ip_address = ipaddress.ip_address(source_ip) if isinstance(allowed_ips, (tuple, list, set)): for ip in allowed_ips: - #TODO: verify - #ip = safe_str(ip) + # TODO: verify + # ip = safe_str(ip) try: network_address = ipaddress.ip_network(ip, strict=False) if source_ip_address in network_address: - log.debug('IP %s is network %s', source_ip_address, network_address) + log.debug("IP %s is network %s", source_ip_address, network_address) return True # for any case we cannot determine the IP, don't crash just # skip it and log as error, we want to say forbidden still when @@ -2529,10 +2499,10 @@ def get_cython_compat_decorator(wrapper, func): :param wrapper: __wrapper method of the decorator class :param func: decorated function """ + @wraps(func) def local_wrapper(*args, **kwds): return wrapper(func, *args, **kwds) + local_wrapper.__wrapped__ = func return local_wrapper - - diff --git a/rhodecode/lib/base.py b/rhodecode/lib/base.py index 68b907e6..e0a98a59 100644 --- a/rhodecode/lib/base.py +++ b/rhodecode/lib/base.py @@ -39,7 +39,7 @@ from rhodecode.lib import auth, utils2 from rhodecode.lib import helpers as h from rhodecode.lib.auth import AuthUser, CookieStoreWrapper from rhodecode.lib.exceptions import UserCreationError -from rhodecode.lib.utils import (password_changed, get_enabled_hook_classes) +from rhodecode.lib.utils import password_changed, get_enabled_hook_classes from rhodecode.lib.utils2 import AttributeDict from rhodecode.lib.str_utils import ascii_bytes, safe_int, safe_str from rhodecode.lib.type_utils import aslist, str2bool @@ -60,10 +60,10 @@ def _filter_proxy(ip): :param ip: ip string from headers """ - if ',' in ip: - _ips = ip.split(',') + if "," in ip: + _ips = ip.split(",") _first_ip = _ips[0].strip() - log.debug('Got multiple IPs %s, using %s', ','.join(_ips), _first_ip) + log.debug("Got multiple IPs %s, using %s", ",".join(_ips), _first_ip) return _first_ip return ip @@ -78,8 +78,9 @@ def _filter_port(ip): :param ip: """ + def is_ipv6(ip_addr): - if hasattr(socket, 'inet_pton'): + if hasattr(socket, "inet_pton"): try: socket.inet_pton(socket.AF_INET6, ip_addr) except socket.error: @@ -92,24 +93,24 @@ def _filter_port(ip): return False return True - if ':' not in ip: # must be ipv4 pure ip + if ":" not in ip: # must be ipv4 pure ip return ip - if '[' in ip and ']' in ip: # ipv6 with port - return ip.split(']')[0][1:].lower() + if "[" in ip and "]" in ip: # ipv6 with port + return ip.split("]")[0][1:].lower() # must be ipv6 or ipv4 with port if is_ipv6(ip): return ip else: - ip, _port = ip.split(':')[:2] # means ipv4+port + ip, _port = ip.split(":")[:2] # means ipv4+port return ip def get_ip_addr(environ): - proxy_key = 'HTTP_X_REAL_IP' - proxy_key2 = 'HTTP_X_FORWARDED_FOR' - def_key = 'REMOTE_ADDR' + proxy_key = "HTTP_X_REAL_IP" + proxy_key2 = "HTTP_X_FORWARDED_FOR" + def_key = "REMOTE_ADDR" def ip_filters(ip_): return _filter_port(_filter_proxy(ip_)) @@ -122,34 +123,41 @@ def get_ip_addr(environ): if ip: return ip_filters(ip) - ip = environ.get(def_key, '0.0.0.0') + ip = environ.get(def_key, "0.0.0.0") return ip_filters(ip) def get_server_ip_addr(environ, log_errors=True): - hostname = environ.get('SERVER_NAME') + hostname = environ.get("SERVER_NAME") try: return socket.gethostbyname(hostname) except Exception as e: if log_errors: # in some cases this lookup is not possible, and we don't want to # make it an exception in logs - log.exception('Could not retrieve server ip address: %s', e) + log.exception("Could not retrieve server ip address: %s", e) return hostname def get_server_port(environ): - return environ.get('SERVER_PORT') - + return environ.get("SERVER_PORT") def get_user_agent(environ): - return environ.get('HTTP_USER_AGENT') + return environ.get("HTTP_USER_AGENT") def vcs_operation_context( - environ, repo_name, username, action, scm, check_locking=True, - is_shadow_repo=False, check_branch_perms=False, detect_force_push=False): + environ, + repo_name, + username, + action, + scm, + check_locking=True, + is_shadow_repo=False, + check_branch_perms=False, + detect_force_push=False, +): """ Generate the context for a vcs operation, e.g. push or pull. @@ -169,44 +177,50 @@ def vcs_operation_context( if not is_anonymous and check_locking: log.debug('Checking locking on repository "%s"', repo_name) repo = Repository.get_by_repo_name(repo_name) - make_lock, __, locked_by = repo.get_locking_state( - action, user.user_id) + make_lock, __, locked_by = repo.get_locking_state(action, user.user_id) user_id = user.user_id settings_model = VcsSettingsModel(repo=repo_name) ui_settings = settings_model.get_ui_settings() # NOTE(marcink): This should be also in sync with # rhodecode/apps/ssh_support/lib/backends/base.py:update_environment scm_data - store = [x for x in ui_settings if x.key == '/'] - repo_store = '' + store = [x for x in ui_settings if x.key == "/"] + repo_store = "" if store: repo_store = store[0].value scm_data = { - 'ip': get_ip_addr(environ), - 'username': username, - 'user_id': user_id, - 'action': action, - 'repository': repo_name, - 'scm': scm, - 'config': rhodecode.CONFIG['__file__'], - 'repo_store': repo_store, - 'make_lock': make_lock, - 'locked_by': locked_by, - 'server_url': utils2.get_server_url(environ), - 'user_agent': get_user_agent(environ), - 'hooks': get_enabled_hook_classes(ui_settings), - 'is_shadow_repo': is_shadow_repo, - 'detect_force_push': detect_force_push, - 'check_branch_perms': check_branch_perms, + "ip": get_ip_addr(environ), + "username": username, + "user_id": user_id, + "action": action, + "repository": repo_name, + "scm": scm, + "config": rhodecode.CONFIG["__file__"], + "repo_store": repo_store, + "make_lock": make_lock, + "locked_by": locked_by, + "server_url": utils2.get_server_url(environ), + "user_agent": get_user_agent(environ), + "hooks": get_enabled_hook_classes(ui_settings), + "is_shadow_repo": is_shadow_repo, + "detect_force_push": detect_force_push, + "check_branch_perms": check_branch_perms, } return scm_data class BasicAuth(AuthBasicAuthenticator): - - def __init__(self, realm, authfunc, registry, auth_http_code=None, - initial_call_detection=False, acl_repo_name=None, rc_realm=''): + def __init__( + self, + realm, + authfunc, + registry, + auth_http_code=None, + initial_call_detection=False, + acl_repo_name=None, + rc_realm="", + ): super().__init__(realm=realm, authfunc=authfunc) self.realm = realm self.rc_realm = rc_realm @@ -220,14 +234,14 @@ class BasicAuth(AuthBasicAuthenticator): try: return get_exception(safe_int(http_code)) except Exception: - log.exception('Failed to fetch response class for code %s, using fallback: %s', http_code, fallback) + log.exception("Failed to fetch response class for code %s, using fallback: %s", http_code, fallback) return fallback def get_rc_realm(self): return safe_str(self.rc_realm) def build_authentication(self): - header = [('WWW-Authenticate', f'Basic realm="{self.realm}"')] + header = [("WWW-Authenticate", f'Basic realm="{self.realm}"')] # NOTE: the initial_Call detection seems to be not working/not needed witg latest Mercurial # investigate if we still need it. @@ -236,7 +250,7 @@ class BasicAuth(AuthBasicAuthenticator): # is specified in RhodeCode config, but ONLY if it's not the # FIRST call custom_response_klass = self._get_response_from_code(self._rc_auth_http_code, fallback=HTTPUnauthorized) - log.debug('Using custom response class: %s', custom_response_klass) + log.debug("Using custom response class: %s", custom_response_klass) return custom_response_klass(headers=header) return HTTPUnauthorized(headers=header) @@ -244,19 +258,19 @@ class BasicAuth(AuthBasicAuthenticator): authorization = paste.httpheaders.AUTHORIZATION(environ) if not authorization: return self.build_authentication() - (auth_meth, auth_creds_b64) = authorization.split(' ', 1) - if 'basic' != auth_meth.lower(): + (auth_meth, auth_creds_b64) = authorization.split(" ", 1) + if "basic" != auth_meth.lower(): return self.build_authentication() credentials = safe_str(base64.b64decode(auth_creds_b64.strip())) - _parts = credentials.split(':', 1) + _parts = credentials.split(":", 1) if len(_parts) == 2: username, password = _parts auth_data = self.authfunc( - username, password, environ, VCS_TYPE, - registry=self.registry, acl_repo_name=self.acl_repo_name) + username, password, environ, VCS_TYPE, registry=self.registry, acl_repo_name=self.acl_repo_name + ) if auth_data: - return {'username': username, 'auth_data': auth_data} + return {"username": username, "auth_data": auth_data} if username and password: # we mark that we actually executed authentication once, at # that point we can use the alternative auth code @@ -268,13 +282,11 @@ class BasicAuth(AuthBasicAuthenticator): def calculate_version_hash(config): - return sha1( - config.get(b'beaker.session.secret', b'') + ascii_bytes(rhodecode.__version__) - )[:8] + return sha1(config.get(b"beaker.session.secret", b"") + ascii_bytes(rhodecode.__version__))[:8] def get_current_lang(request): - return getattr(request, '_LOCALE_', request.locale_name) + return getattr(request, "_LOCALE_", request.locale_name) def attach_context_attributes(context, request, user_id=None, is_api=None): @@ -286,8 +298,8 @@ def attach_context_attributes(context, request, user_id=None, is_api=None): rc_config = SettingsModel().get_all_settings(cache=True, from_request=False) context.rc_config = rc_config context.rhodecode_version = rhodecode.__version__ - context.rhodecode_edition = config.get('rhodecode.edition') - context.rhodecode_edition_id = config.get('rhodecode.edition_id') + context.rhodecode_edition = config.get("rhodecode.edition") + context.rhodecode_edition_id = config.get("rhodecode.edition_id") # unique secret + version does not leak the version but keep consistency context.rhodecode_version_hash = calculate_version_hash(config) @@ -298,131 +310,95 @@ def attach_context_attributes(context, request, user_id=None, is_api=None): context.visual = AttributeDict({}) # DB stored Visual Items - context.visual.show_public_icon = str2bool( - rc_config.get('rhodecode_show_public_icon')) - context.visual.show_private_icon = str2bool( - rc_config.get('rhodecode_show_private_icon')) - context.visual.stylify_metatags = str2bool( - rc_config.get('rhodecode_stylify_metatags')) - context.visual.dashboard_items = safe_int( - rc_config.get('rhodecode_dashboard_items', 100)) - context.visual.admin_grid_items = safe_int( - rc_config.get('rhodecode_admin_grid_items', 100)) - context.visual.show_revision_number = str2bool( - rc_config.get('rhodecode_show_revision_number', True)) - context.visual.show_sha_length = safe_int( - rc_config.get('rhodecode_show_sha_length', 100)) - context.visual.repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) - context.visual.show_version = str2bool( - rc_config.get('rhodecode_show_version')) - context.visual.use_gravatar = str2bool( - rc_config.get('rhodecode_use_gravatar')) - context.visual.gravatar_url = rc_config.get('rhodecode_gravatar_url') - context.visual.default_renderer = rc_config.get( - 'rhodecode_markup_renderer', 'rst') + context.visual.show_public_icon = str2bool(rc_config.get("rhodecode_show_public_icon")) + context.visual.show_private_icon = str2bool(rc_config.get("rhodecode_show_private_icon")) + context.visual.stylify_metatags = str2bool(rc_config.get("rhodecode_stylify_metatags")) + context.visual.dashboard_items = safe_int(rc_config.get("rhodecode_dashboard_items", 100)) + context.visual.admin_grid_items = safe_int(rc_config.get("rhodecode_admin_grid_items", 100)) + context.visual.show_revision_number = str2bool(rc_config.get("rhodecode_show_revision_number", True)) + context.visual.show_sha_length = safe_int(rc_config.get("rhodecode_show_sha_length", 100)) + context.visual.repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) + context.visual.show_version = str2bool(rc_config.get("rhodecode_show_version")) + context.visual.use_gravatar = str2bool(rc_config.get("rhodecode_use_gravatar")) + context.visual.gravatar_url = rc_config.get("rhodecode_gravatar_url") + context.visual.default_renderer = rc_config.get("rhodecode_markup_renderer", "rst") context.visual.comment_types = ChangesetComment.COMMENT_TYPES - context.visual.rhodecode_support_url = \ - rc_config.get('rhodecode_support_url') or h.route_url('rhodecode_support') + context.visual.rhodecode_support_url = rc_config.get("rhodecode_support_url") or h.route_url("rhodecode_support") context.visual.affected_files_cut_off = 60 - context.pre_code = rc_config.get('rhodecode_pre_code') - context.post_code = rc_config.get('rhodecode_post_code') - context.rhodecode_name = rc_config.get('rhodecode_title') - context.default_encodings = aslist(config.get('default_encoding'), sep=',') + context.pre_code = rc_config.get("rhodecode_pre_code") + context.post_code = rc_config.get("rhodecode_post_code") + context.rhodecode_name = rc_config.get("rhodecode_title") + context.default_encodings = aslist(config.get("default_encoding"), sep=",") # if we have specified default_encoding in the request, it has more # priority - if request.GET.get('default_encoding'): - context.default_encodings.insert(0, request.GET.get('default_encoding')) - context.clone_uri_tmpl = rc_config.get('rhodecode_clone_uri_tmpl') - context.clone_uri_id_tmpl = rc_config.get('rhodecode_clone_uri_id_tmpl') - context.clone_uri_ssh_tmpl = rc_config.get('rhodecode_clone_uri_ssh_tmpl') + if request.GET.get("default_encoding"): + context.default_encodings.insert(0, request.GET.get("default_encoding")) + context.clone_uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") + context.clone_uri_id_tmpl = rc_config.get("rhodecode_clone_uri_id_tmpl") + context.clone_uri_ssh_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") # INI stored - context.labs_active = str2bool( - config.get('labs_settings_active', 'false')) - context.ssh_enabled = str2bool( - config.get('ssh.generate_authorized_keyfile', 'false')) - context.ssh_key_generator_enabled = str2bool( - config.get('ssh.enable_ui_key_generator', 'true')) + context.labs_active = str2bool(config.get("labs_settings_active", "false")) + context.ssh_enabled = str2bool(config.get("ssh.generate_authorized_keyfile", "false")) + context.ssh_key_generator_enabled = str2bool(config.get("ssh.enable_ui_key_generator", "true")) - context.visual.allow_custom_hooks_settings = str2bool( - config.get('allow_custom_hooks_settings', True)) - context.debug_style = str2bool(config.get('debug_style', False)) + context.visual.allow_custom_hooks_settings = str2bool(config.get("allow_custom_hooks_settings", True)) + context.debug_style = str2bool(config.get("debug_style", False)) - context.rhodecode_instanceid = config.get('instance_id') + context.rhodecode_instanceid = config.get("instance_id") - context.visual.cut_off_limit_diff = safe_int( - config.get('cut_off_limit_diff'), default=0) - context.visual.cut_off_limit_file = safe_int( - config.get('cut_off_limit_file'), default=0) + context.visual.cut_off_limit_diff = safe_int(config.get("cut_off_limit_diff"), default=0) + context.visual.cut_off_limit_file = safe_int(config.get("cut_off_limit_file"), default=0) context.license = AttributeDict({}) - context.license.hide_license_info = str2bool( - config.get('license.hide_license_info', False)) + context.license.hide_license_info = str2bool(config.get("license.hide_license_info", False)) # AppEnlight - context.appenlight_enabled = config.get('appenlight', False) - context.appenlight_api_public_key = config.get( - 'appenlight.api_public_key', '') - context.appenlight_server_url = config.get('appenlight.server_url', '') + context.appenlight_enabled = config.get("appenlight", False) + context.appenlight_api_public_key = config.get("appenlight.api_public_key", "") + context.appenlight_server_url = config.get("appenlight.server_url", "") - diffmode = { - "unified": "unified", - "sideside": "sideside" - }.get(request.GET.get('diffmode')) + diffmode = {"unified": "unified", "sideside": "sideside"}.get(request.GET.get("diffmode")) if is_api is not None: - is_api = hasattr(request, 'rpc_user') + is_api = hasattr(request, "rpc_user") session_attrs = { # defaults "clone_url_format": "http", "diffmode": "sideside", - "license_fingerprint": request.session.get('license_fingerprint') + "license_fingerprint": request.session.get("license_fingerprint"), } if not is_api: # don't access pyramid session for API calls - if diffmode and diffmode != request.session.get('rc_user_session_attr.diffmode'): - request.session['rc_user_session_attr.diffmode'] = diffmode + if diffmode and diffmode != request.session.get("rc_user_session_attr.diffmode"): + request.session["rc_user_session_attr.diffmode"] = diffmode # session settings per user for k, v in list(request.session.items()): - pref = 'rc_user_session_attr.' + pref = "rc_user_session_attr." if k and k.startswith(pref): - k = k[len(pref):] + k = k[len(pref) :] session_attrs[k] = v context.user_session_attrs = session_attrs # JS template context context.template_context = { - 'repo_name': None, - 'repo_type': None, - 'repo_landing_commit': None, - 'rhodecode_user': { - 'username': None, - 'email': None, - 'notification_status': False - }, - 'session_attrs': session_attrs, - 'visual': { - 'default_renderer': None - }, - 'commit_data': { - 'commit_id': None - }, - 'pull_request_data': {'pull_request_id': None}, - 'timeago': { - 'refresh_time': 120 * 1000, - 'cutoff_limit': 1000 * 60 * 60 * 24 * 7 - }, - 'pyramid_dispatch': { - - }, - 'extra': {'plugins': {}} + "repo_name": None, + "repo_type": None, + "repo_landing_commit": None, + "rhodecode_user": {"username": None, "email": None, "notification_status": False}, + "session_attrs": session_attrs, + "visual": {"default_renderer": None}, + "commit_data": {"commit_id": None}, + "pull_request_data": {"pull_request_id": None}, + "timeago": {"refresh_time": 120 * 1000, "cutoff_limit": 1000 * 60 * 60 * 24 * 7}, + "pyramid_dispatch": {}, + "extra": {"plugins": {}}, } # END CONFIG VARS if is_api: @@ -442,12 +418,12 @@ def attach_context_attributes(context, request, user_id=None, is_api=None): context.bookmark_items = user_bookmark_list # web case - if hasattr(request, 'user'): + if hasattr(request, "user"): context.auth_user = request.user context.rhodecode_user = request.user # api case - if hasattr(request, 'rpc_user'): + if hasattr(request, "rpc_user"): context.auth_user = request.rpc_user context.rhodecode_user = request.rpc_user @@ -463,18 +439,18 @@ def get_auth_user(request): # make sure that we update permissions each time we call controller _auth_token = ( - # ?auth_token=XXX - request.GET.get('auth_token', '') - # ?api_key=XXX !LEGACY - or request.GET.get('api_key', '') - # or headers.... - or request.headers.get('X-Rc-Auth-Token', '') + # ?auth_token=XXX + request.GET.get("auth_token", "") + # ?api_key=XXX !LEGACY + or request.GET.get("api_key", "") + # or headers.... + or request.headers.get("X-Rc-Auth-Token", "") ) if not _auth_token and request.matchdict: - url_auth_token = request.matchdict.get('_auth_token') + url_auth_token = request.matchdict.get("_auth_token") _auth_token = url_auth_token if _auth_token: - log.debug('Using URL extracted auth token `...%s`', _auth_token[-4:]) + log.debug("Using URL extracted auth token `...%s`", _auth_token[-4:]) if _auth_token: # when using API_KEY we assume user exists, and @@ -482,12 +458,11 @@ def get_auth_user(request): auth_user = AuthUser(api_key=_auth_token, ip_addr=ip_addr) authenticated = False else: - cookie_store = CookieStoreWrapper(session.get('rhodecode_user')) + cookie_store = CookieStoreWrapper(session.get("rhodecode_user")) try: - auth_user = AuthUser(user_id=cookie_store.get('user_id', None), - ip_addr=ip_addr) + auth_user = AuthUser(user_id=cookie_store.get("user_id", None), ip_addr=ip_addr) except UserCreationError as e: - h.flash(e, 'error') + h.flash(e, "error") # container auth or other auth functions that create users # on the fly can throw this exception signaling that there's # issue with user creation, explanation should be provided @@ -499,10 +474,10 @@ def get_auth_user(request): # flush and forces a re-login if password_changed(auth_user, session): session.invalidate() - cookie_store = CookieStoreWrapper(session.get('rhodecode_user')) + cookie_store = CookieStoreWrapper(session.get("rhodecode_user")) auth_user = AuthUser(ip_addr=ip_addr) - authenticated = cookie_store.get('is_authenticated') + authenticated = cookie_store.get("is_authenticated") if not auth_user.is_authenticated and auth_user.is_user_object: # user is not authenticated and not empty @@ -531,54 +506,47 @@ def add_events_routes(config): from rhodecode.apps._base import ADMIN_PREFIX - config.add_route(name='home', pattern='/') - config.add_route(name='main_page_repos_data', pattern='/_home_repos') - config.add_route(name='main_page_repo_groups_data', pattern='/_home_repo_groups') + config.add_route(name="home", pattern="/") + config.add_route(name="main_page_repos_data", pattern="/_home_repos") + config.add_route(name="main_page_repo_groups_data", pattern="/_home_repo_groups") - config.add_route(name='login', pattern=ADMIN_PREFIX + '/login') - config.add_route(name='logout', pattern=ADMIN_PREFIX + '/logout') - config.add_route(name='repo_summary', pattern='/{repo_name}') - config.add_route(name='repo_summary_explicit', pattern='/{repo_name}/summary') - config.add_route(name='repo_group_home', pattern='/{repo_group_name}') + config.add_route(name="login", pattern=ADMIN_PREFIX + "/login") + config.add_route(name="logout", pattern=ADMIN_PREFIX + "/logout") + config.add_route(name="repo_summary", pattern="/{repo_name}") + config.add_route(name="repo_summary_explicit", pattern="/{repo_name}/summary") + config.add_route(name="repo_group_home", pattern="/{repo_group_name}") - config.add_route(name='pullrequest_show', - pattern='/{repo_name}/pull-request/{pull_request_id}') - config.add_route(name='pull_requests_global', - pattern='/pull-request/{pull_request_id}') + config.add_route(name="pullrequest_show", pattern="/{repo_name}/pull-request/{pull_request_id}") + config.add_route(name="pull_requests_global", pattern="/pull-request/{pull_request_id}") - config.add_route(name='repo_commit', - pattern='/{repo_name}/changeset/{commit_id}') - config.add_route(name='repo_files', - pattern='/{repo_name}/files/{commit_id}/{f_path}') + config.add_route(name="repo_commit", pattern="/{repo_name}/changeset/{commit_id}") + config.add_route(name="repo_files", pattern="/{repo_name}/files/{commit_id}/{f_path}") - config.add_route(name='hovercard_user', - pattern='/_hovercard/user/{user_id}') + config.add_route(name="hovercard_user", pattern="/_hovercard/user/{user_id}") - config.add_route(name='hovercard_user_group', - pattern='/_hovercard/user_group/{user_group_id}') + config.add_route(name="hovercard_user_group", pattern="/_hovercard/user_group/{user_group_id}") - config.add_route(name='hovercard_pull_request', - pattern='/_hovercard/pull_request/{pull_request_id}') + config.add_route(name="hovercard_pull_request", pattern="/_hovercard/pull_request/{pull_request_id}") - config.add_route(name='hovercard_repo_commit', - pattern='/_hovercard/commit/{repo_name}/{commit_id}') + config.add_route(name="hovercard_repo_commit", pattern="/_hovercard/commit/{repo_name}/{commit_id}") -def bootstrap_config(request, registry_name='RcTestRegistry'): +def bootstrap_config(request, registry_name="RcTestRegistry"): from rhodecode.config.config_maker import sanitize_settings_and_apply_defaults import pyramid.testing + registry = pyramid.testing.Registry(registry_name) - global_config = {'__file__': ''} + global_config = {"__file__": ""} config = pyramid.testing.setUp(registry=registry, request=request) sanitize_settings_and_apply_defaults(global_config, config.registry.settings) # allow pyramid lookup in testing - config.include('pyramid_mako') - config.include('rhodecode.lib.rc_beaker') - config.include('rhodecode.lib.rc_cache') - config.include('rhodecode.lib.archive_cache') + config.include("pyramid_mako") + config.include("rhodecode.lib.rc_beaker") + config.include("rhodecode.lib.rc_cache") + config.include("rhodecode.lib.archive_cache") add_events_routes(config) return config @@ -593,9 +561,9 @@ def bootstrap_request(**kwargs): from rhodecode.lib.request import ThinRequest as _ThinRequest class ThinRequest(_ThinRequest): - application_url = kwargs.pop('application_url', 'http://example.com') - host = kwargs.pop('host', 'example.com:80') - domain = kwargs.pop('domain', 'example.com') + application_url = kwargs.pop("application_url", "http://example.com") + host = kwargs.pop("host", "example.com:80") + domain = kwargs.pop("domain", "example.com") class ThinSession(pyramid.testing.DummySession): def save(*arg, **kw): diff --git a/rhodecode/lib/caching_query.py b/rhodecode/lib/caching_query.py index b50012a7..b8bb01ab 100644 --- a/rhodecode/lib/caching_query.py +++ b/rhodecode/lib/caching_query.py @@ -39,6 +39,7 @@ The rest of what's here are standard SQLAlchemy and dogpile.cache constructs. """ + from dogpile.cache.api import NO_VALUE from sqlalchemy import event @@ -50,7 +51,6 @@ DEFAULT_REGION = "sql_cache_short" class ORMCache: - """An add-on for an ORM :class:`.Session` optionally loads full results from a dogpile cache region. @@ -66,6 +66,7 @@ class ORMCache: @classmethod def _get_region(cls): from rhodecode.lib.rc_cache import region_meta + return region_meta.dogpile_cache_regions def listen_on_session(self, session_factory): @@ -86,11 +87,9 @@ class ORMCache: continue if opt.cache_key: - our_cache_key = f'SQL_CACHE_{opt.cache_key}' + our_cache_key = f"SQL_CACHE_{opt.cache_key}" else: - our_cache_key = opt._generate_cache_key( - orm_context.statement, orm_context.parameters, self - ) + our_cache_key = opt._generate_cache_key(orm_context.statement, orm_context.parameters, self) if opt.ignore_expiration: cached_value = dogpile_region.get( @@ -181,9 +180,9 @@ class FromCache(UserDefinedOption): """ statement_cache_key = statement._generate_cache_key() - key = statement_cache_key.to_offline_string( - orm_cache._statement_cache, statement, parameters - ) + repr(self.cache_key) + key = statement_cache_key.to_offline_string(orm_cache._statement_cache, statement, parameters) + repr( + self.cache_key + ) # print("here's our key...%s" % key) return key @@ -219,9 +218,7 @@ class RelationshipCache(FromCache): self.cache_key = cache_key self.expiration_time = expiration_time self.ignore_expiration = ignore_expiration - self._relationship_options = { - (attribute.property.parent.class_, attribute.property.key): self - } + self._relationship_options = {(attribute.property.parent.class_, attribute.property.key): self} def _process_orm_context(self, orm_context): current_path = orm_context.loader_strategy_path @@ -232,9 +229,7 @@ class RelationshipCache(FromCache): for cls in mapper.class_.__mro__: if (cls, key) in self._relationship_options: - relationship_option = self._relationship_options[ - (cls, key) - ] + relationship_option = self._relationship_options[(cls, key)] return relationship_option def and_(self, option): @@ -247,4 +242,3 @@ class RelationshipCache(FromCache): """ self._relationship_options.update(option._relationship_options) return self - diff --git a/rhodecode/lib/celerylib/__init__.py b/rhodecode/lib/celerylib/__init__.py index c241504d..0399a16b 100644 --- a/rhodecode/lib/celerylib/__init__.py +++ b/rhodecode/lib/celerylib/__init__.py @@ -21,8 +21,7 @@ import logging import rhodecode from zope.cachedescriptors.property import Lazy as LazyProperty -from rhodecode.lib.celerylib.loader import ( - celery_app, RequestContextTask, get_logger) +from rhodecode.lib.celerylib.loader import celery_app, RequestContextTask, get_logger from rhodecode.lib.statsd_client import StatsdClient async_task = celery_app.task @@ -42,9 +41,10 @@ class ResultWrapper(object): def run_task(task, *args, **kwargs): import celery - log.debug('Got task `%s` for execution, celery mode enabled:%s', task, rhodecode.CELERY_ENABLED) + + log.debug("Got task `%s` for execution, celery mode enabled:%s", task, rhodecode.CELERY_ENABLED) if task is None: - raise ValueError(f'Got non-existing task: {task} for execution') + raise ValueError(f"Got non-existing task: {task} for execution") allow_async = True @@ -52,39 +52,33 @@ def run_task(task, *args, **kwargs): # e.g task within task in_task = celery.current_task if in_task: - log.debug('This task in in context of another task: %s, not allowing another async execution', in_task) + log.debug("This task in in context of another task: %s, not allowing another async execution", in_task) allow_async = False - if kwargs.pop('allow_subtask', False): - log.debug('Forced async by allow_async=True flag') + if kwargs.pop("allow_subtask", False): + log.debug("Forced async by allow_async=True flag") allow_async = True t = None if rhodecode.CELERY_ENABLED and allow_async: - try: t = task.apply_async(args=args, kwargs=kwargs) - log.debug('executing task %s:%s in async mode', t.task_id, task) + log.debug("executing task %s:%s in async mode", t.task_id, task) except socket.error as e: if isinstance(e, IOError) and e.errno == 111: - log.error('Unable to connect to celeryd `%s`. Sync execution', e) + log.error("Unable to connect to celeryd `%s`. Sync execution", e) else: log.exception("Exception while connecting to celeryd.") except KeyError as e: - log.error('Unable to connect to celeryd `%s`. Sync execution', e) + log.error("Unable to connect to celeryd `%s`. Sync execution", e) except Exception as e: - log.exception( - "Exception while trying to run task asynchronous. " - "Fallback to sync execution.") + log.exception("Exception while trying to run task asynchronous. Fallback to sync execution.") else: - log.debug('executing task %s:%s in sync mode', 'TASK', task) + log.debug("executing task %s:%s in sync mode", "TASK", task) statsd = StatsdClient.statsd if statsd: - task_repr = getattr(task, 'name', task) - statsd.incr('rhodecode_celery_task_total', tags=[ - f'task:{task_repr}', - 'mode:sync' - ]) + task_repr = getattr(task, "name", task) + statsd.incr("rhodecode_celery_task_total", tags=[f"task:{task_repr}", "mode:sync"]) # we got async task, return it after statsd call if t: diff --git a/rhodecode/lib/celerylib/loader.py b/rhodecode/lib/celerylib/loader.py index 37e47bc5..e26f18aa 100644 --- a/rhodecode/lib/celerylib/loader.py +++ b/rhodecode/lib/celerylib/loader.py @@ -27,7 +27,9 @@ Celery loader, run with:: --scheduler rhodecode.lib.celerylib.scheduler.RcScheduler \ --loglevel DEBUG --ini=.dev/dev.ini """ + from rhodecode.config import patches + patches.inspect_getargspec() patches.inspect_formatargspec() # python3.11 inspect patches for backward compat on `paste` code @@ -52,54 +54,46 @@ from rhodecode.lib.pyramid_utils import bootstrap, setup_logging from rhodecode.lib.utils2 import str2bool from rhodecode.model import meta -log = logging.getLogger('celery.rhodecode.loader') +log = logging.getLogger("celery.rhodecode.loader") -imports = ['rhodecode.lib.celerylib.tasks'] +imports = ["rhodecode.lib.celerylib.tasks"] try: # try if we have EE tasks available - importlib.import_module('rc_ee') - imports.append('rc_ee.lib.celerylib.tasks') + importlib.import_module("rc_ee") + imports.append("rc_ee.lib.celerylib.tasks") except ImportError: pass base_celery_config = { - 'result_backend': 'rpc://', - 'result_expires': 60 * 60 * 24, - 'result_persistent': True, - 'imports': imports, - 'worker_max_tasks_per_child': 100, - 'worker_hijack_root_logger': False, - 'worker_prefetch_multiplier': 1, - 'task_serializer': 'json', - 'accept_content': ['json', 'msgpack'], - 'result_serializer': 'json', - 'result_accept_content': ['json', 'msgpack'], - - 'broker_connection_retry_on_startup': True, - 'database_table_names': { - 'task': 'beat_taskmeta', - 'group': 'beat_groupmeta', - } + "result_backend": "rpc://", + "result_expires": 60 * 60 * 24, + "result_persistent": True, + "imports": imports, + "worker_max_tasks_per_child": 100, + "worker_hijack_root_logger": False, + "worker_prefetch_multiplier": 1, + "task_serializer": "json", + "accept_content": ["json", "msgpack"], + "result_serializer": "json", + "result_accept_content": ["json", "msgpack"], + "broker_connection_retry_on_startup": True, + "database_table_names": { + "task": "beat_taskmeta", + "group": "beat_groupmeta", + }, } -preload_option_ini = click.Option( - ('--ini',), - help='Path to ini configuration file.' -) +preload_option_ini = click.Option(("--ini",), help="Path to ini configuration file.") -preload_option_ini_var = click.Option( - ('--ini-var',), - help='Comma separated list of key=value to pass to ini.' -) +preload_option_ini_var = click.Option(("--ini-var",), help="Comma separated list of key=value to pass to ini.") def get_logger(obj): - custom_log = logging.getLogger( - 'rhodecode.task.{}'.format(obj.__class__.__name__)) + custom_log = logging.getLogger("rhodecode.task.{}".format(obj.__class__.__name__)) if rhodecode.CELERY_ENABLED: try: @@ -112,80 +106,84 @@ def get_logger(obj): # init main celery app celery_app = Celery() -celery_app.user_options['preload'].add(preload_option_ini) -celery_app.user_options['preload'].add(preload_option_ini_var) +celery_app.user_options["preload"].add(preload_option_ini) +celery_app.user_options["preload"].add(preload_option_ini_var) @signals.setup_logging.connect def setup_logging_callback(**kwargs): - - if 'RC_INI_FILE' in celery_app.conf: - ini_file = celery_app.conf['RC_INI_FILE'] + if "RC_INI_FILE" in celery_app.conf: + ini_file = celery_app.conf["RC_INI_FILE"] else: - ini_file = celery_app.user_options['RC_INI_FILE'] + ini_file = celery_app.user_options["RC_INI_FILE"] setup_logging(ini_file) @signals.user_preload_options.connect def on_preload_parsed(options, **kwargs): - - ini_file = options['ini'] - ini_vars = options['ini_var'] + ini_file = options["ini"] + ini_vars = options["ini_var"] if ini_file is None: - print('You must provide the --ini argument to start celery') + print("You must provide the --ini argument to start celery") exit(-1) options = None if ini_vars is not None: options = parse_ini_vars(ini_vars) - celery_app.conf['RC_INI_FILE'] = ini_file - celery_app.user_options['RC_INI_FILE'] = ini_file + celery_app.conf["RC_INI_FILE"] = ini_file + celery_app.user_options["RC_INI_FILE"] = ini_file - celery_app.conf['RC_INI_OPTIONS'] = options - celery_app.user_options['RC_INI_OPTIONS'] = options + celery_app.conf["RC_INI_OPTIONS"] = options + celery_app.user_options["RC_INI_OPTIONS"] = options setup_logging(ini_file) -def _init_celery(app_type=''): +def _init_celery(app_type=""): from rhodecode.config.middleware import get_celery_config - log.debug('Bootstrapping RhodeCode application for %s...', app_type) + log.debug("Bootstrapping RhodeCode application for %s...", app_type) - ini_file = celery_app.conf['RC_INI_FILE'] - options = celery_app.conf['RC_INI_OPTIONS'] + ini_file = celery_app.conf["RC_INI_FILE"] + options = celery_app.conf["RC_INI_OPTIONS"] env = None try: env = bootstrap(ini_file, options=options) except Exception: - log.exception('Failed to bootstrap RhodeCode APP. ' - 'Probably there is another error present that prevents from running pyramid app') + log.exception( + "Failed to bootstrap RhodeCode APP. " + "Probably there is another error present that prevents from running pyramid app" + ) if not env: # we use sys.exit here since we need to signal app startup failure for docker to restart the container and re-try sys.exit(1) - log.debug('Got Pyramid ENV: %s', env) + log.debug("Got Pyramid ENV: %s", env) - settings = env['registry'].settings + settings = env["registry"].settings celery_settings = get_celery_config(settings) # init and bootstrap StatsdClient StatsdClient.setup(settings) setup_celery_app( - app=env['app'], root=env['root'], request=env['request'], - registry=env['registry'], closer=env['closer'], - celery_settings=celery_settings) + app=env["app"], + root=env["root"], + request=env["request"], + registry=env["registry"], + closer=env["closer"], + celery_settings=celery_settings, + ) @signals.celeryd_init.connect def on_celeryd_init(sender=None, conf=None, **kwargs): - _init_celery('celery worker') + _init_celery("celery worker") # fix the global flag even if it's disabled via .ini file because this # is a worker code that doesn't need this to be disabled. @@ -194,7 +192,7 @@ def on_celeryd_init(sender=None, conf=None, **kwargs): @signals.beat_init.connect def on_beat_init(sender=None, conf=None, **kwargs): - _init_celery('celery beat') + _init_celery("celery beat") @signals.task_prerun.connect @@ -203,35 +201,29 @@ def task_prerun_signal(task_id, task, args, **kwargs): statsd = StatsdClient.statsd if statsd: - task_repr = getattr(task, 'name', task) - statsd.incr('rhodecode_celery_task_total', tags=[ - f'task:{task_repr}', - 'mode:async' - ]) + task_repr = getattr(task, "name", task) + statsd.incr("rhodecode_celery_task_total", tags=[f"task:{task_repr}", "mode:async"]) @signals.task_success.connect def task_success_signal(result, **kwargs): meta.Session.commit() - closer = celery_app.conf['PYRAMID_CLOSER'] + closer = celery_app.conf["PYRAMID_CLOSER"] if closer: closer() @signals.task_retry.connect -def task_retry_signal( - request, reason, einfo, **kwargs): +def task_retry_signal(request, reason, einfo, **kwargs): meta.Session.remove() - closer = celery_app.conf['PYRAMID_CLOSER'] + closer = celery_app.conf["PYRAMID_CLOSER"] if closer: closer() @signals.task_failure.connect -def task_failure_signal( - task_id, exception, args, kwargs, traceback, einfo, **kargs): - - log.error('Task: %s failed !! exc_info: %s', task_id, einfo) +def task_failure_signal(task_id, exception, args, kwargs, traceback, einfo, **kargs): + log.error("Task: %s failed !! exc_info: %s", task_id, einfo) from rhodecode.lib.exc_tracking import store_exception from rhodecode.lib.statsd_client import StatsdClient @@ -239,22 +231,20 @@ def task_failure_signal( # simulate sys.exc_info() exc_info = (einfo.type, einfo.exception, einfo.tb) - store_exception(id(exc_info), exc_info, prefix='rhodecode-celery') + store_exception(id(exc_info), exc_info, prefix="rhodecode-celery") statsd = StatsdClient.statsd if statsd: exc_type = "{}.{}".format(einfo.__class__.__module__, einfo.__class__.__name__) - statsd.incr('rhodecode_exception_total', - tags=["exc_source:celery", "type:{}".format(exc_type)]) + statsd.incr("rhodecode_exception_total", tags=["exc_source:celery", "type:{}".format(exc_type)]) - closer = celery_app.conf['PYRAMID_CLOSER'] + closer = celery_app.conf["PYRAMID_CLOSER"] if closer: closer() @signals.task_revoked.connect -def task_revoked_signal( - request, terminated, signum, expired, **kwargs): - closer = celery_app.conf['PYRAMID_CLOSER'] +def task_revoked_signal(request, terminated, signum, expired, **kwargs): + closer = celery_app.conf["PYRAMID_CLOSER"] if closer: closer() @@ -267,30 +257,31 @@ _unset = UNSET() def set_celery_conf(app=_unset, root=_unset, request=_unset, registry=_unset, closer=_unset): - if request is not UNSET: - celery_app.conf.update({'PYRAMID_REQUEST': request}) + celery_app.conf.update({"PYRAMID_REQUEST": request}) if registry is not UNSET: - celery_app.conf.update({'PYRAMID_REGISTRY': registry}) + celery_app.conf.update({"PYRAMID_REGISTRY": registry}) def setup_celery_app(app, root, request, registry, closer, celery_settings): - log.debug('Got custom celery conf: %s', celery_settings) + log.debug("Got custom celery conf: %s", celery_settings) celery_config = base_celery_config - celery_config.update({ - # store celerybeat scheduler db where the .ini file is - 'beat_schedule_filename': registry.settings['celerybeat-schedule.path'], - }) + celery_config.update( + { + # store celerybeat scheduler db where the .ini file is + "beat_schedule_filename": registry.settings["celerybeat-schedule.path"], + } + ) celery_config.update(celery_settings) celery_app.config_from_object(celery_config) - celery_app.conf.update({'PYRAMID_APP': app}) - celery_app.conf.update({'PYRAMID_ROOT': root}) - celery_app.conf.update({'PYRAMID_REQUEST': request}) - celery_app.conf.update({'PYRAMID_REGISTRY': registry}) - celery_app.conf.update({'PYRAMID_CLOSER': closer}) + celery_app.conf.update({"PYRAMID_APP": app}) + celery_app.conf.update({"PYRAMID_ROOT": root}) + celery_app.conf.update({"PYRAMID_REQUEST": request}) + celery_app.conf.update({"PYRAMID_REGISTRY": registry}) + celery_app.conf.update({"PYRAMID_CLOSER": closer}) def configure_celery(config, celery_settings): @@ -300,26 +291,27 @@ def configure_celery(config, celery_settings): RhodeCode itself """ # store some globals into rhodecode - rhodecode.CELERY_ENABLED = str2bool( - config.registry.settings.get('use_celery')) + rhodecode.CELERY_ENABLED = str2bool(config.registry.settings.get("use_celery")) if rhodecode.CELERY_ENABLED: - log.info('Configuring celery based on `%s` settings', celery_settings) + log.info("Configuring celery based on `%s` settings", celery_settings) setup_celery_app( - app=None, root=None, request=None, registry=config.registry, - closer=None, celery_settings=celery_settings) + app=None, root=None, request=None, registry=config.registry, closer=None, celery_settings=celery_settings + ) def maybe_prepare_env(req): environ = {} try: - environ.update({ - 'PATH_INFO': req.environ['PATH_INFO'], - 'SCRIPT_NAME': req.environ['SCRIPT_NAME'], - 'HTTP_HOST': req.environ.get('HTTP_HOST', req.environ['SERVER_NAME']), - 'SERVER_NAME': req.environ['SERVER_NAME'], - 'SERVER_PORT': req.environ['SERVER_PORT'], - 'wsgi.url_scheme': req.environ['wsgi.url_scheme'], - }) + environ.update( + { + "PATH_INFO": req.environ["PATH_INFO"], + "SCRIPT_NAME": req.environ["SCRIPT_NAME"], + "HTTP_HOST": req.environ.get("HTTP_HOST", req.environ["SERVER_NAME"]), + "SERVER_NAME": req.environ["SERVER_NAME"], + "SERVER_PORT": req.environ["SERVER_PORT"], + "wsgi.url_scheme": req.environ["wsgi.url_scheme"], + } + ) except Exception: pass @@ -333,41 +325,41 @@ class RequestContextTask(Task): that created the task and also add the user to the context. """ - def apply_async(self, args=None, kwargs=None, task_id=None, producer=None, - link=None, link_error=None, shadow=None, **options): - """ queue the job to run (we are in web request context here) """ + def apply_async( + self, args=None, kwargs=None, task_id=None, producer=None, link=None, link_error=None, shadow=None, **options + ): + """queue the job to run (we are in web request context here)""" from rhodecode.lib.base import get_ip_addr - req = self.app.conf['PYRAMID_REQUEST'] + req = self.app.conf["PYRAMID_REQUEST"] if not req: - raise ValueError('celery_app.conf is having empty PYRAMID_REQUEST key') + raise ValueError("celery_app.conf is having empty PYRAMID_REQUEST key") - log.debug('Running Task with class: %s. Request Class: %s', - self.__class__, req.__class__) + log.debug("Running Task with class: %s. Request Class: %s", self.__class__, req.__class__) user_id = 0 # web case - if hasattr(req, 'user'): + if hasattr(req, "user"): user_id = req.user.user_id # api case - elif hasattr(req, 'rpc_user'): + elif hasattr(req, "rpc_user"): user_id = req.rpc_user.user_id # we hook into kwargs since it is the only way to pass our data to # the celery worker environ = maybe_prepare_env(req) - options['headers'] = options.get('headers', {}) - options['headers'].update({ - 'rhodecode_proxy_data': { - 'environ': environ, - 'auth_user': { - 'ip_addr': get_ip_addr(req.environ), - 'user_id': user_id - }, + options["headers"] = options.get("headers", {}) + options["headers"].update( + { + "rhodecode_proxy_data": { + "environ": environ, + "auth_user": {"ip_addr": get_ip_addr(req.environ), "user_id": user_id}, + } } - }) + ) return super(RequestContextTask, self).apply_async( - args, kwargs, task_id, producer, link, link_error, shadow, **options) + args, kwargs, task_id, producer, link, link_error, shadow, **options + ) diff --git a/rhodecode/lib/celerylib/scheduler.py b/rhodecode/lib/celerylib/scheduler.py index 1e91babd..fd630291 100644 --- a/rhodecode/lib/celerylib/scheduler.py +++ b/rhodecode/lib/celerylib/scheduler.py @@ -18,16 +18,26 @@ import logging import importlib -from celery.beat import ( - PersistentScheduler, ScheduleEntry as CeleryScheduleEntry) +from celery.beat import PersistentScheduler, ScheduleEntry as CeleryScheduleEntry log = logging.getLogger(__name__) class FileScheduleEntry(CeleryScheduleEntry): - def __init__(self, name=None, task=None, last_run_at=None, - total_run_count=None, schedule=None, args=(), kwargs=None, - options=None, relative=False, app=None, **_kwargs): + def __init__( + self, + name=None, + task=None, + last_run_at=None, + total_run_count=None, + schedule=None, + args=(), + kwargs=None, + options=None, + relative=False, + app=None, + **_kwargs, + ): kwargs = kwargs or {} options = options or {} @@ -35,13 +45,22 @@ class FileScheduleEntry(CeleryScheduleEntry): # function doesn't expect, we have this thin wrapper super().__init__( - name=name, task=task, last_run_at=last_run_at, - total_run_count=total_run_count, schedule=schedule, args=args, - kwargs=kwargs, options=options, relative=relative, app=app) + name=name, + task=task, + last_run_at=last_run_at, + total_run_count=total_run_count, + schedule=schedule, + args=args, + kwargs=kwargs, + options=options, + relative=relative, + app=app, + ) class FileScheduler(PersistentScheduler): """CE base scheduler""" + Entry = FileScheduleEntry def setup_schedule(self): @@ -51,7 +70,7 @@ class FileScheduler(PersistentScheduler): try: # try if we have EE scheduler available - module = importlib.import_module('rc_ee.lib.celerylib.scheduler') + module = importlib.import_module("rc_ee.lib.celerylib.scheduler") RcScheduler = module.RcScheduler except ImportError: # fallback to CE scheduler diff --git a/rhodecode/lib/celerylib/tasks.py b/rhodecode/lib/celerylib/tasks.py index 9cb04363..8da73f67 100644 --- a/rhodecode/lib/celerylib/tasks.py +++ b/rhodecode/lib/celerylib/tasks.py @@ -35,14 +35,12 @@ from rhodecode.lib import hooks_base from rhodecode.lib.utils import adopt_for_celery from rhodecode.lib.utils2 import safe_int, str2bool, aslist from rhodecode.lib.statsd_client import StatsdClient -from rhodecode.model.db import ( - true, null, Session, IntegrityError, Repository, RepoGroup, User) +from rhodecode.model.db import true, null, Session, IntegrityError, Repository, RepoGroup, User from rhodecode.model.permission import PermissionModel @async_task(ignore_result=True, base=RequestContextTask) -def send_email(recipients, subject, body='', html_body='', email_config=None, - extra_headers=None): +def send_email(recipients, subject, body="", html_body="", email_config=None, extra_headers=None): """ Sends an email with defined parameters from the .ini files. @@ -58,19 +56,21 @@ def send_email(recipients, subject, body='', html_body='', email_config=None, email_config = email_config or rhodecode.CONFIG - mail_server = email_config.get('smtp_server') or None + mail_server = email_config.get("smtp_server") or None if mail_server is None: - log.error("SMTP server information missing. Sending email failed. " - "Make sure that `smtp_server` variable is configured " - "inside the .ini file") + log.error( + "SMTP server information missing. Sending email failed. " + "Make sure that `smtp_server` variable is configured " + "inside the .ini file" + ) return False - conf_prefix = email_config.get('email_prefix', None) - prefix = f'{conf_prefix} ' if conf_prefix else '' + conf_prefix = email_config.get("email_prefix", None) + prefix = f"{conf_prefix} " if conf_prefix else "" subject = f"{prefix}{subject}" if recipients: if isinstance(recipients, str): - recipients = recipients.split(',') + recipients = recipients.split(",") else: # if recipients are not defined we send to email_config + all admins admins = [] @@ -78,7 +78,7 @@ def send_email(recipients, subject, body='', html_body='', email_config=None, if u.email: admins.append(u.email) recipients = [] - config_email = email_config.get('email_to') + config_email = email_config.get("email_to") if config_email: recipients += [config_email] recipients += admins @@ -86,28 +86,21 @@ def send_email(recipients, subject, body='', html_body='', email_config=None, # translate our LEGACY config into the one that pyramid_mailer supports email_conf = dict( host=mail_server, - port=email_config.get('smtp_port', 25), - username=email_config.get('smtp_username', None), - password=email_config.get('smtp_password', None), - - tls=str2bool(email_config.get('smtp_use_tls')), - ssl=str2bool(email_config.get('smtp_use_ssl')), - + port=email_config.get("smtp_port", 25), + username=email_config.get("smtp_username", None), + password=email_config.get("smtp_password", None), + tls=str2bool(email_config.get("smtp_use_tls")), + ssl=str2bool(email_config.get("smtp_use_ssl")), # SSL key file # keyfile='', - # SSL certificate file # certfile='', - # Location of maildir # queue_path='', - - default_sender=email_config.get('app_email_from', 'RhodeCode-noreply@rhodecode.com'), - - debug=str2bool(email_config.get('smtp_debug')), + default_sender=email_config.get("app_email_from", "RhodeCode-noreply@rhodecode.com"), + debug=str2bool(email_config.get("smtp_debug")), # /usr/sbin/sendmail Sendmail executable # sendmail_app='', - # {sendmail_app} -t -i -f {sender} Template for sendmail execution # sendmail_template='', ) @@ -115,27 +108,30 @@ def send_email(recipients, subject, body='', html_body='', email_config=None, if extra_headers is None: extra_headers = {} - extra_headers.setdefault('Date', formatdate(time.time())) + extra_headers.setdefault("Date", formatdate(time.time())) - if 'thread_ids' in extra_headers: - thread_ids = extra_headers.pop('thread_ids') - extra_headers['References'] = ' '.join('<{}>'.format(t) for t in thread_ids) + if "thread_ids" in extra_headers: + thread_ids = extra_headers.pop("thread_ids") + extra_headers["References"] = " ".join("<{}>".format(t) for t in thread_ids) try: mailer = Mailer(**email_conf) - message = Message(subject=subject, - sender=email_conf['default_sender'], - recipients=recipients, - body=body, html=html_body, - extra_headers=extra_headers) + message = Message( + subject=subject, + sender=email_conf["default_sender"], + recipients=recipients, + body=body, + html=html_body, + extra_headers=extra_headers, + ) mailer.send_immediately(message) statsd = StatsdClient.statsd if statsd: - statsd.incr('rhodecode_email_sent_total') + statsd.incr("rhodecode_email_sent_total") except Exception: - log.exception('Mail sending failed') + log.exception("Mail sending failed") return False return True @@ -152,26 +148,23 @@ def create_repo(form_data, cur_user): cur_user = UserModel()._get_user(cur_user) owner = cur_user - repo_name = form_data['repo_name'] - repo_name_full = form_data['repo_name_full'] - repo_type = form_data['repo_type'] - description = form_data['repo_description'] - private = form_data['repo_private'] - clone_uri = form_data.get('clone_uri') - repo_group = safe_int(form_data['repo_group']) - copy_fork_permissions = form_data.get('copy_permissions') - copy_group_permissions = form_data.get('repo_copy_permissions') - fork_of = form_data.get('fork_parent_id') - state = form_data.get('repo_state', Repository.STATE_PENDING) + repo_name = form_data["repo_name"] + repo_name_full = form_data["repo_name_full"] + repo_type = form_data["repo_type"] + description = form_data["repo_description"] + private = form_data["repo_private"] + clone_uri = form_data.get("clone_uri") + repo_group = safe_int(form_data["repo_group"]) + copy_fork_permissions = form_data.get("copy_permissions") + copy_group_permissions = form_data.get("repo_copy_permissions") + fork_of = form_data.get("fork_parent_id") + state = form_data.get("repo_state", Repository.STATE_PENDING) # repo creation defaults, private and repo_type are filled in form defs = SettingsModel().get_default_repo_settings(strip_prefix=True) - enable_statistics = form_data.get( - 'enable_statistics', defs.get('repo_enable_statistics')) - enable_locking = form_data.get( - 'enable_locking', defs.get('repo_enable_locking')) - enable_downloads = form_data.get( - 'enable_downloads', defs.get('repo_enable_downloads')) + enable_statistics = form_data.get("enable_statistics", defs.get("repo_enable_statistics")) + enable_locking = form_data.get("enable_locking", defs.get("repo_enable_locking")) + enable_downloads = form_data.get("enable_downloads", defs.get("repo_enable_downloads")) # set landing rev based on default branches for SCM landing_ref, _label = ScmModel.backend_landing_ref(repo_type) @@ -192,7 +185,7 @@ def create_repo(form_data, cur_user): enable_statistics=enable_statistics, enable_locking=enable_locking, enable_downloads=enable_downloads, - state=state + state=state, ) Session().commit() @@ -216,17 +209,18 @@ def create_repo(form_data, cur_user): repo_data = repo.get_api_data() audit_logger.store( - 'repo.create', action_data={'data': repo_data}, + "repo.create", + action_data={"data": repo_data}, user=cur_user, - repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id)) + repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id), + ) Session().commit() PermissionModel().trigger_permission_flush() except Exception as e: - log.warning('Exception occurred when creating repository, ' - 'doing cleanup...', exc_info=True) + log.warning("Exception occurred when creating repository, doing cleanup...", exc_info=True) if isinstance(e, IntegrityError): Session().rollback() @@ -236,7 +230,7 @@ def create_repo(form_data, cur_user): Repository.delete(repo.repo_id) Session().commit() RepoModel()._delete_filesystem_repo(repo) - log.info('Cleanup of repo %s finished', repo_name_full) + log.info("Cleanup of repo %s finished", repo_name_full) raise return True @@ -255,16 +249,16 @@ def create_repo_fork(form_data, cur_user): cur_user = UserModel()._get_user(cur_user) owner = cur_user - repo_name = form_data['repo_name'] # fork in this case - repo_name_full = form_data['repo_name_full'] - repo_type = form_data['repo_type'] - description = form_data['description'] - private = form_data['private'] - clone_uri = form_data.get('clone_uri') - repo_group = safe_int(form_data['repo_group']) - landing_ref = form_data['landing_rev'] - copy_fork_permissions = form_data.get('copy_permissions') - fork_id = safe_int(form_data.get('fork_parent_id')) + repo_name = form_data["repo_name"] # fork in this case + repo_name_full = form_data["repo_name_full"] + repo_type = form_data["repo_type"] + description = form_data["description"] + private = form_data["private"] + clone_uri = form_data.get("clone_uri") + repo_group = safe_int(form_data["repo_group"]) + landing_ref = form_data["landing_rev"] + copy_fork_permissions = form_data.get("copy_permissions") + fork_id = safe_int(form_data.get("fork_parent_id")) try: fork_of = RepoModel()._get_repo(fork_id) @@ -278,7 +272,7 @@ def create_repo_fork(form_data, cur_user): repo_group=repo_group, landing_rev=landing_ref, fork_of=fork_of, - copy_fork_permissions=copy_fork_permissions + copy_fork_permissions=copy_fork_permissions, ) Session().commit() @@ -298,7 +292,7 @@ def create_repo_fork(form_data, cur_user): # update repo commit caches initially config = repo._config - config.set('extensions', 'largefiles', '') + config.set("extensions", "largefiles", "") repo.update_commit_cache(config=config, recursive=False) # set new created state @@ -307,14 +301,15 @@ def create_repo_fork(form_data, cur_user): repo_id = repo.repo_id repo_data = repo.get_api_data() audit_logger.store( - 'repo.fork', action_data={'data': repo_data}, + "repo.fork", + action_data={"data": repo_data}, user=cur_user, - repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id)) + repo=audit_logger.RepoWrap(repo_name=repo_name, repo_id=repo_id), + ) Session().commit() except Exception as e: - log.warning('Exception occurred when forking repository, ' - 'doing cleanup...', exc_info=True) + log.warning("Exception occurred when forking repository, doing cleanup...", exc_info=True) if isinstance(e, IntegrityError): Session().rollback() @@ -324,7 +319,7 @@ def create_repo_fork(form_data, cur_user): Repository.delete(repo.repo_id) Session().commit() RepoModel()._delete_filesystem_repo(repo) - log.info('Cleanup of repo %s finished', repo_name_full) + log.info("Cleanup of repo %s finished", repo_name_full) raise return True @@ -333,16 +328,17 @@ def create_repo_fork(form_data, cur_user): @async_task(ignore_result=True, base=RequestContextTask) def repo_maintenance(repoid): from rhodecode.lib import repo_maintenance as repo_maintenance_lib + log = get_logger(repo_maintenance) repo = Repository.get_by_id_or_repo_name(repoid) if repo: maintenance = repo_maintenance_lib.RepoMaintenance() tasks = maintenance.get_tasks_for_repo(repo) - log.debug('Executing %s tasks on repo `%s`', tasks, repoid) + log.debug("Executing %s tasks on repo `%s`", tasks, repoid) executed_types = maintenance.execute(repo) - log.debug('Got execution results %s', executed_types) + log.debug("Got execution results %s", executed_types) else: - log.debug('Repo `%s` not found or without a clone_url', repoid) + log.debug("Repo `%s` not found or without a clone_url", repoid) @async_task(ignore_result=True, base=RequestContextTask) @@ -358,45 +354,46 @@ def check_for_update(send_email_notification=True, email_recipients=None): data = UpdateModel().get_update_data(update_url) current_ver = UpdateModel().get_stored_version(fallback=cur_ver) - latest_ver = data['versions'][0]['version'] + latest_ver = data["versions"][0]["version"] UpdateModel().store_version(latest_ver) if send_email_notification: - log.debug('Send email notification is enabled. ' - 'Current RhodeCode version: %s, latest known: %s', current_ver, latest_ver) + log.debug( + "Send email notification is enabled. Current RhodeCode version: %s, latest known: %s", + current_ver, + latest_ver, + ) if UpdateModel().is_outdated(current_ver, latest_ver): - email_kwargs = { - 'current_ver': current_ver, - 'latest_ver': latest_ver, + "current_ver": current_ver, + "latest_ver": latest_ver, } (subject, email_body, email_body_plaintext) = EmailNotificationModel().render_email( - EmailNotificationModel.TYPE_UPDATE_AVAILABLE, **email_kwargs) + EmailNotificationModel.TYPE_UPDATE_AVAILABLE, **email_kwargs + ) - email_recipients = aslist(email_recipients, sep=',') or \ - [user.email for user in User.get_all_super_admins()] - run_task(send_email, email_recipients, subject, - email_body_plaintext, email_body) + email_recipients = aslist(email_recipients, sep=",") or [ + user.email for user in User.get_all_super_admins() + ] + run_task(send_email, email_recipients, subject, email_body_plaintext, email_body) except Exception: - log.exception('Failed to check for update') + log.exception("Failed to check for update") raise def sync_last_update_for_objects(*args, **kwargs): - skip_repos = kwargs.get('skip_repos') + skip_repos = kwargs.get("skip_repos") if not skip_repos: - repos = Repository.query() \ - .order_by(Repository.group_id.asc()) + repos = Repository.query().order_by(Repository.group_id.asc()) for repo in repos: repo.update_commit_cache(recursive=False) - skip_groups = kwargs.get('skip_groups') + skip_groups = kwargs.get("skip_groups") if not skip_groups: - repo_groups = RepoGroup.query() \ - .filter(RepoGroup.group_parent_id == null()) + repo_groups = RepoGroup.query().filter(RepoGroup.group_parent_id == null()) for root_gr in repo_groups: for repo_gr in reversed(root_gr.recursive_groups()): @@ -405,7 +402,7 @@ def sync_last_update_for_objects(*args, **kwargs): @async_task(ignore_result=True, base=RequestContextTask) def test_celery_exception(msg): - raise Exception(f'Test exception: {msg}') + raise Exception(f"Test exception: {msg}") @async_task(ignore_result=True, base=RequestContextTask) @@ -416,7 +413,7 @@ def sync_last_update(*args, **kwargs): @async_task(ignore_result=False) def beat_check(*args, **kwargs): log = get_logger(beat_check) - log.info('%r: Got args: %r and kwargs %r', beat_check, args, kwargs) + log.info("%r: Got args: %r and kwargs %r", beat_check, args, kwargs) return time.time() @@ -424,6 +421,7 @@ def beat_check(*args, **kwargs): @adopt_for_celery def repo_size(extras): from rhodecode.lib.hooks_base import repo_size + return repo_size(extras) @@ -431,6 +429,7 @@ def repo_size(extras): @adopt_for_celery def pre_pull(extras): from rhodecode.lib.hooks_base import pre_pull + return pre_pull(extras) @@ -438,6 +437,7 @@ def pre_pull(extras): @adopt_for_celery def post_pull(extras): from rhodecode.lib.hooks_base import post_pull + return post_pull(extras) @@ -445,6 +445,7 @@ def post_pull(extras): @adopt_for_celery def pre_push(extras): from rhodecode.lib.hooks_base import pre_push + return pre_push(extras) @@ -452,4 +453,5 @@ def pre_push(extras): @adopt_for_celery def post_push(extras): from rhodecode.lib.hooks_base import post_push + return post_push(extras) diff --git a/rhodecode/lib/celerylib/utils.py b/rhodecode/lib/celerylib/utils.py index dcf5852f..b4260ab3 100644 --- a/rhodecode/lib/celerylib/utils.py +++ b/rhodecode/lib/celerylib/utils.py @@ -49,90 +49,86 @@ def timedelta(value): def safe_json(get, section, key): - value = '' + value = "" try: value = get(key) json_value = json.loads(value) except ValueError: - msg = f'The {key}={value} is not valid json in section {section}' + msg = f"The {key}={value} is not valid json in section {section}" raise ValueError(msg) return json_value def raw_2_schedule(schedule_value, schedule_type): - schedule_type_map = { - 'crontab': crontab, - 'timedelta': timedelta, - 'integer': int - } + schedule_type_map = {"crontab": crontab, "timedelta": timedelta, "integer": int} scheduler_cls = schedule_type_map.get(schedule_type) if scheduler_cls is None: - raise ValueError(f'schedule type {schedule_type} in section is invalid') + raise ValueError(f"schedule type {schedule_type} in section is invalid") try: schedule = scheduler_cls(schedule_value) except TypeError: - log.exception('Failed to compose a schedule from value: %r', schedule_value) + log.exception("Failed to compose a schedule from value: %r", schedule_value) schedule = None return schedule def get_beat_config(parser, section): - get = partial(parser.get, section) has_option = partial(parser.has_option, section) - schedule_type = get('type') - schedule_value = safe_json(get, section, 'schedule') + schedule_type = get("type") + schedule_value = safe_json(get, section, "schedule") config = { - 'schedule_type': schedule_type, - 'schedule_value': schedule_value, - 'task': get('task'), + "schedule_type": schedule_type, + "schedule_value": schedule_value, + "task": get("task"), } schedule = raw_2_schedule(schedule_value, schedule_type) if schedule: - config['schedule'] = schedule + config["schedule"] = schedule - if has_option('args'): - config['args'] = safe_json(get, section, 'args') + if has_option("args"): + config["args"] = safe_json(get, section, "args") - if has_option('kwargs'): - config['kwargs'] = safe_json(get, section, 'kwargs') + if has_option("kwargs"): + config["kwargs"] = safe_json(get, section, "kwargs") - if has_option('force_update'): - config['force_update'] = get('force_update') + if has_option("force_update"): + config["force_update"] = get("force_update") return config def parse_ini_vars(ini_vars): options = {} - for pairs in ini_vars.split(','): - key, value = pairs.split('=') + for pairs in ini_vars.split(","): + key, value = pairs.split("=") options[key] = value return options def ping_db(): - log.info('Testing DB connection...') + log.info("Testing DB connection...") from sqlalchemy import text from rhodecode.model import meta + qry = text("SELECT user_id from users where username = :uname") for test in range(10): try: engine = meta.get_engine() with meta.SA_Session(engine) as session: - result = session.execute(qry, {'uname': 'default'}) + result = session.execute(qry, {"uname": "default"}) user_id = result.first()[0] - log.debug('DB PING user_id:%s', user_id) + log.debug("DB PING user_id:%s", user_id) break except Exception: retry = 1 - log.debug('DB not ready, next try in %ss', retry) + log.debug("DB not ready, next try in %ss", retry) time.sleep(retry) finally: meta.Session.remove() diff --git a/rhodecode/lib/channelstream.py b/rhodecode/lib/channelstream.py index ea0c0846..36f25209 100644 --- a/rhodecode/lib/channelstream.py +++ b/rhodecode/lib/channelstream.py @@ -35,9 +35,7 @@ log = logging.getLogger(__name__) LOCK = ReadWriteMutex() -USER_STATE_PUBLIC_KEYS = [ - 'id', 'username', 'first_name', 'last_name', - 'icon_link', 'display_name', 'display_link'] +USER_STATE_PUBLIC_KEYS = ["id", "username", "first_name", "last_name", "icon_link", "display_name", "display_link"] class ChannelstreamException(Exception): @@ -53,67 +51,63 @@ class ChannelstreamPermissionException(ChannelstreamException): def get_channelstream_server_url(config, endpoint): - return 'http://{}{}'.format(config['server'], endpoint) + return "http://{}{}".format(config["server"], endpoint) def channelstream_request(config, payload, endpoint, raise_exc=True): - signer = itsdangerous.TimestampSigner(config['secret']) + signer = itsdangerous.TimestampSigner(config["secret"]) sig_for_server = signer.sign(endpoint) - secret_headers = {'x-channelstream-secret': sig_for_server, - 'x-channelstream-endpoint': endpoint, - 'Content-Type': 'application/json'} + secret_headers = { + "x-channelstream-secret": sig_for_server, + "x-channelstream-endpoint": endpoint, + "Content-Type": "application/json", + } req_url = get_channelstream_server_url(config, endpoint) - log.debug('Sending a channelstream request to endpoint: `%s`', req_url) + log.debug("Sending a channelstream request to endpoint: `%s`", req_url) response = None try: - response = requests.post(req_url, data=json.dumps(payload), - headers=secret_headers).json() + response = requests.post(req_url, data=json.dumps(payload), headers=secret_headers).json() except requests.ConnectionError: - log.exception('ConnectionError occurred for endpoint %s', req_url) + log.exception("ConnectionError occurred for endpoint %s", req_url) if raise_exc: raise ChannelstreamConnectionException(req_url) except Exception: - log.exception('Exception related to Channelstream happened') + log.exception("Exception related to Channelstream happened") if raise_exc: raise ChannelstreamConnectionException() - log.debug('Got channelstream response: %s', response) + log.debug("Got channelstream response: %s", response) return response def get_user_data(user_id): user = User.get(user_id) return { - 'id': user.user_id, - 'username': user.username, - 'first_name': user.first_name, - 'last_name': user.last_name, - 'icon_link': h.gravatar_url(user.email, 60), - 'display_name': h.person(user, 'username_or_name_or_email'), - 'display_link': h.link_to_user(user), - 'notifications': user.user_data.get('notification_status', True) + "id": user.user_id, + "username": user.username, + "first_name": user.first_name, + "last_name": user.last_name, + "icon_link": h.gravatar_url(user.email, 60), + "display_name": h.person(user, "username_or_name_or_email"), + "display_link": h.link_to_user(user), + "notifications": user.user_data.get("notification_status", True), } def broadcast_validator(channel_name): - """ checks if user can access the broadcast channel """ - if channel_name == 'broadcast': + """checks if user can access the broadcast channel""" + if channel_name == "broadcast": return True def repo_validator(channel_name): - """ checks if user can access the broadcast channel """ - channel_prefix = '/repo$' + """checks if user can access the broadcast channel""" + channel_prefix = "/repo$" if channel_name.startswith(channel_prefix): - elements = channel_name[len(channel_prefix):].split('$') + elements = channel_name[len(channel_prefix) :].split("$") repo_name = elements[0] - can_access = HasRepoPermissionAny( - 'repository.read', - 'repository.write', - 'repository.admin')(repo_name) - log.debug( - 'permission check for %s channel resulted in %s', - repo_name, can_access) + can_access = HasRepoPermissionAny("repository.read", "repository.write", "repository.admin")(repo_name) + log.debug("permission check for %s channel resulted in %s", repo_name, can_access) if can_access: return True return False @@ -140,9 +134,9 @@ def check_channel_permissions(channels, plugin_validators, should_raise=True): def get_channels_info(self, channels): - payload = {'channels': channels} + payload = {"channels": channels} # gather persistence info - return channelstream_request(self._config(), payload, '/info') + return channelstream_request(self._config(), payload, "/info") def parse_channels_info(info_result, include_channel_info=None): @@ -153,33 +147,27 @@ def parse_channels_info(info_result, include_channel_info=None): include_channel_info = include_channel_info or [] user_state_dict = {} - for userinfo in info_result['users']: - user_state_dict[userinfo['user']] = { - k: v for k, v in list(userinfo['state'].items()) - if k in USER_STATE_PUBLIC_KEYS - } + for userinfo in info_result["users"]: + user_state_dict[userinfo["user"]] = { + k: v for k, v in list(userinfo["state"].items()) if k in USER_STATE_PUBLIC_KEYS + } channels_info = {} - for c_name, c_info in list(info_result['channels'].items()): + for c_name, c_info in list(info_result["channels"].items()): if c_name not in include_channel_info: continue connected_list = [] - for username in c_info['users']: - connected_list.append({ - 'user': username, - 'state': user_state_dict[username] - }) - channels_info[c_name] = {'users': connected_list, - 'history': c_info['history']} + for username in c_info["users"]: + connected_list.append({"user": username, "state": user_state_dict[username]}) + channels_info[c_name] = {"users": connected_list, "history": c_info["history"]} return channels_info def log_filepath(history_location, channel_name): - - channel_hash = sha1_safe(channel_name, return_type='str') - filename = f'{channel_hash}.log' + channel_hash = sha1_safe(channel_name, return_type="str") + filename = f"{channel_hash}.log" filepath = os.path.join(history_location, filename) return filepath @@ -190,34 +178,34 @@ def read_history(history_location, channel_name): return [] history_lines_limit = -100 history = [] - with open(filepath, 'rb') as f: + with open(filepath, "rb") as f: for line in f.readlines()[history_lines_limit:]: try: history.append(json.loads(line)) except Exception: - log.exception('Failed to load history') + log.exception("Failed to load history") return history def update_history_from_logs(config, channels, payload): - history_location = config.get('history.location') + history_location = config.get("history.location") for channel in channels: history = read_history(history_location, channel) - payload['channels_info'][channel]['history'] = history + payload["channels_info"][channel]["history"] = history def write_history(config, message): - """ writes a message to a base64encoded filename """ - history_location = config.get('history.location') + """writes a message to a base64encoded filename""" + history_location = config.get("history.location") if not os.path.exists(history_location): return try: LOCK.acquire_write_lock() - filepath = log_filepath(history_location, message['channel']) + filepath = log_filepath(history_location, message["channel"]) json_message = json.dumps(message) - with open(filepath, 'ab') as f: + with open(filepath, "ab") as f: f.write(json_message) - f.write(b'\n') + f.write(b"\n") finally: LOCK.release_write_lock() @@ -225,7 +213,7 @@ def write_history(config, message): def get_connection_validators(registry): validators = [] for k, config in list(registry.rhodecode_plugins.items()): - validator = config.get('channelstream', {}).get('connect_validator') + validator = config.get("channelstream", {}).get("connect_validator") if validator: validators.append(validator) return validators @@ -234,72 +222,59 @@ def get_connection_validators(registry): def get_channelstream_config(registry=None): if not registry: from pyramid.threadlocal import get_current_registry + registry = get_current_registry() - rhodecode_plugins = getattr(registry, 'rhodecode_plugins', {}) - channelstream_config = rhodecode_plugins.get('channelstream', {}) + rhodecode_plugins = getattr(registry, "rhodecode_plugins", {}) + channelstream_config = rhodecode_plugins.get("channelstream", {}) return channelstream_config def post_message(channel, message, username, registry=None): channelstream_config = get_channelstream_config(registry) - if not channelstream_config.get('enabled'): + if not channelstream_config.get("enabled"): return message_obj = message if isinstance(message, str): - message_obj = { - 'message': message, - 'level': 'success', - 'topic': '/notifications' - } + message_obj = {"message": message, "level": "success", "topic": "/notifications"} - log.debug('Channelstream: sending notification to channel %s', channel) + log.debug("Channelstream: sending notification to channel %s", channel) payload = { - 'type': 'message', - 'timestamp': datetime.datetime.utcnow(), - 'user': 'system', - 'exclude_users': [username], - 'channel': channel, - 'message': message_obj + "type": "message", + "timestamp": datetime.datetime.utcnow(), + "user": "system", + "exclude_users": [username], + "channel": channel, + "message": message_obj, } try: - return channelstream_request( - channelstream_config, [payload], '/message', - raise_exc=False) + return channelstream_request(channelstream_config, [payload], "/message", raise_exc=False) except ChannelstreamException: - log.exception('Failed to send channelstream data') + log.exception("Failed to send channelstream data") raise def _reload_link(label): - return ( - '' - '{}' - ''.format(label) - ) + return '{}'.format(label) def pr_channel(pull_request): repo_name = pull_request.target_repo.repo_name pull_request_id = pull_request.pull_request_id - channel = f'/repo${repo_name}$/pr/{pull_request_id}' - log.debug('Getting pull-request channelstream broadcast channel: %s', channel) + channel = f"/repo${repo_name}$/pr/{pull_request_id}" + log.debug("Getting pull-request channelstream broadcast channel: %s", channel) return channel def comment_channel(repo_name, commit_obj=None, pull_request_obj=None): channel = None if commit_obj: - channel = '/repo${}$/commit/{}'.format( - repo_name, commit_obj.raw_id - ) + channel = "/repo${}$/commit/{}".format(repo_name, commit_obj.raw_id) elif pull_request_obj: - channel = '/repo${}$/pr/{}'.format( - repo_name, pull_request_obj.pull_request_id - ) - log.debug('Getting comment channelstream broadcast channel: %s', channel) + channel = "/repo${}$/pr/{}".format(repo_name, pull_request_obj.pull_request_id) + log.debug("Getting comment channelstream broadcast channel: %s", channel) return channel @@ -313,19 +288,11 @@ def pr_update_channelstream_push(request, pr_broadcast_channel, user, msg, **kwa _ = request.translate - message = '{} {}'.format( - msg, - _reload_link(_(' Reload page to load changes'))) + message = "{} {}".format(msg, _reload_link(_(" Reload page to load changes"))) - message_obj = { - 'message': message, - 'level': 'success', - 'topic': '/notifications' - } + message_obj = {"message": message, "level": "success", "topic": "/notifications"} - post_message( - pr_broadcast_channel, message_obj, user.username, - registry=request.registry) + post_message(pr_broadcast_channel, message_obj, user.username, registry=request.registry) def comment_channelstream_push(request, comment_broadcast_channel, user, msg, **kwargs): @@ -337,34 +304,26 @@ def comment_channelstream_push(request, comment_broadcast_channel, user, msg, ** _ = request.translate - comment_data = kwargs.pop('comment_data', {}) - user_data = kwargs.pop('user_data', {}) - comment_id = list(comment_data.keys())[0] if comment_data else '' + comment_data = kwargs.pop("comment_data", {}) + user_data = kwargs.pop("user_data", {}) + comment_id = list(comment_data.keys())[0] if comment_data else "" - message = '{} {} #{}'.format( + message = "{} {} #{}".format( user.username, msg, comment_id, ) - message_obj = { - 'message': message, - 'level': 'success', - 'topic': '/notifications' - } + message_obj = {"message": message, "level": "success", "topic": "/notifications"} - post_message( - comment_broadcast_channel, message_obj, user.username, - registry=request.registry) + post_message(comment_broadcast_channel, message_obj, user.username, registry=request.registry) message_obj = { - 'message': None, - 'user': user.username, - 'comment_id': comment_id, - 'comment_data': comment_data, - 'user_data': user_data, - 'topic': '/comment' + "message": None, + "user": user.username, + "comment_id": comment_id, + "comment_data": comment_data, + "user_data": user_data, + "topic": "/comment", } - post_message( - comment_broadcast_channel, message_obj, user.username, - registry=request.registry) + post_message(comment_broadcast_channel, message_obj, user.username, registry=request.registry) diff --git a/rhodecode/lib/codeblocks.py b/rhodecode/lib/codeblocks.py index 0a475ae2..683dada9 100644 --- a/rhodecode/lib/codeblocks.py +++ b/rhodecode/lib/codeblocks.py @@ -25,8 +25,7 @@ from pygments.formatters.html import _get_ttype_class as pygment_token_class from pygments.lexers.special import TextLexer, Token from pygments.lexers import get_lexer_by_name -from rhodecode.lib.helpers import ( - get_lexer_for_filenode, html_escape, get_custom_lexer) +from rhodecode.lib.helpers import get_lexer_for_filenode, html_escape, get_custom_lexer from rhodecode.lib.str_utils import safe_str from rhodecode.lib.utils2 import AttributeDict, StrictAttributeDict from rhodecode.lib.vcs.nodes import FileNode @@ -35,8 +34,7 @@ from rhodecode.lib.diff_match_patch import diff_match_patch from rhodecode.lib.diffs import LimitedDiffContainer, DEL_FILENODE, BIN_FILENODE -plain_text_lexer = get_lexer_by_name( - 'text', stripall=False, stripnl=False, ensurenl=False) +plain_text_lexer = get_lexer_by_name("text", stripall=False, stripnl=False, ensurenl=False) log = logging.getLogger(__name__) @@ -45,8 +43,7 @@ log = logging.getLogger(__name__) def filenode_as_lines_tokens(filenode, lexer=None): org_lexer = lexer lexer = lexer or get_lexer_for_filenode(filenode) - log.debug('Generating file node pygment tokens for %s, file=`%s`, org_lexer:%s', - lexer, filenode, org_lexer) + log.debug("Generating file node pygment tokens for %s, file=`%s`, org_lexer:%s", lexer, filenode, org_lexer) content = filenode.str_content tokens = tokenize_string(content, lexer) lines = split_token_stream(tokens, content) @@ -90,9 +87,8 @@ def split_token_stream(tokens, content): token_buffer = [] for token_class, token_text in tokens: - # token_text, should be str - parts = token_text.split('\n') + parts = token_text.split("\n") for part in parts[:-1]: token_buffer.append((token_class, part)) yield token_buffer @@ -143,36 +139,31 @@ def filenode_as_annotated_lines_tokens(filenode): annotation_lookup = { line_no: _get_annotation(commit_id, commit_getter) - for line_no, commit_id, commit_getter, line_content - in filenode.annotate + for line_no, commit_id, commit_getter, line_content in filenode.annotate } - annotations_lines = ((annotation_lookup.get(line_no), line_no, tokens) - for line_no, tokens - in enumerate(filenode_as_lines_tokens(filenode), 1)) + annotations_lines = ( + (annotation_lookup.get(line_no), line_no, tokens) + for line_no, tokens in enumerate(filenode_as_lines_tokens(filenode), 1) + ) grouped_annotations_lines = itertools.groupby(annotations_lines, lambda x: x[0]) for annotation, group in grouped_annotations_lines: - yield ( - annotation, [(line_no, tokens) - for (_, line_no, tokens) in group] - ) + yield (annotation, [(line_no, tokens) for (_, line_no, tokens) in group]) def render_tokenstream(tokenstream): result = [] for token_class, token_ops_texts in rollup_tokenstream(tokenstream): - if token_class: result.append(f'') else: - result.append('') + result.append("") for op_tag, token_text in token_ops_texts: - if op_tag: - result.append(f'<{op_tag}>') + result.append(f"<{op_tag}>") # NOTE(marcink): in some cases of mixed encodings, we might run into # troubles in the html_escape, in this case we say unicode force on token_text @@ -190,11 +181,11 @@ def render_tokenstream(tokenstream): result.append(escaped_text) if op_tag: - result.append(f'') + result.append(f"") - result.append('') + result.append("") - html = ''.join(result) + html = "".join(result) return html @@ -239,7 +230,7 @@ def rollup_tokenstream(tokenstream): """ if tokenstream and len(tokenstream[0]) == 2: - tokenstream = ((t[0], '', t[1]) for t in tokenstream) + tokenstream = ((t[0], "", t[1]) for t in tokenstream) result = [] for token_class, op_list in itertools.groupby(tokenstream, lambda t: t[0]): @@ -249,7 +240,7 @@ def rollup_tokenstream(tokenstream): for t_class, t_op, t_text in token_text_list: text_buffer.append(t_text) - ops.append((token_op, ''.join(text_buffer))) + ops.append((token_op, "".join(text_buffer))) result.append((token_class, ops)) return result @@ -277,38 +268,35 @@ def tokens_diff(old_tokens, new_tokens, use_diff_match_patch=True): similarity = difflib.SequenceMatcher( None, - ''.join(token_text for token_class, token_text in old_tokens), - ''.join(token_text for token_class, token_text in new_tokens) + "".join(token_text for token_class, token_text in old_tokens), + "".join(token_text for token_class, token_text in new_tokens), ).ratio() if similarity < 0.6: # return, the blocks are too different for token_class, token_text in old_tokens: - old_tokens_result.append((token_class, '', token_text)) + old_tokens_result.append((token_class, "", token_text)) for token_class, token_text in new_tokens: - new_tokens_result.append((token_class, '', token_text)) + new_tokens_result.append((token_class, "", token_text)) return old_tokens_result, new_tokens_result, similarity - token_sequence_matcher = difflib.SequenceMatcher( - None, - [x[1] for x in old_tokens], - [x[1] for x in new_tokens]) + token_sequence_matcher = difflib.SequenceMatcher(None, [x[1] for x in old_tokens], [x[1] for x in new_tokens]) for tag, o1, o2, n1, n2 in token_sequence_matcher.get_opcodes(): # check the differences by token block types first to give a # nicer "block" level replacement vs character diffs - if tag == 'equal': + if tag == "equal": for token_class, token_text in old_tokens[o1:o2]: - old_tokens_result.append((token_class, '', token_text)) + old_tokens_result.append((token_class, "", token_text)) for token_class, token_text in new_tokens[n1:n2]: - new_tokens_result.append((token_class, '', token_text)) - elif tag == 'delete': + new_tokens_result.append((token_class, "", token_text)) + elif tag == "delete": for token_class, token_text in old_tokens[o1:o2]: - old_tokens_result.append((token_class, 'del', int_convert(token_text))) - elif tag == 'insert': + old_tokens_result.append((token_class, "del", int_convert(token_text))) + elif tag == "insert": for token_class, token_text in new_tokens[n1:n2]: - new_tokens_result.append((token_class, 'ins', int_convert(token_text))) - elif tag == 'replace': + new_tokens_result.append((token_class, "ins", int_convert(token_text))) + elif tag == "replace": # if same type token blocks must be replaced, do a diff on the # characters in the token blocks to show individual changes @@ -322,13 +310,10 @@ def tokens_diff(old_tokens, new_tokens, use_diff_match_patch=True): for char in map(lambda i: i, token_text): new_char_tokens.append((token_class, char)) - old_string = ''.join([token_text for - token_class, token_text in old_char_tokens]) - new_string = ''.join([token_text for - token_class, token_text in new_char_tokens]) + old_string = "".join([token_text for token_class, token_text in old_char_tokens]) + new_string = "".join([token_text for token_class, token_text in new_char_tokens]) - char_sequence = difflib.SequenceMatcher( - None, old_string, new_string) + char_sequence = difflib.SequenceMatcher(None, old_string, new_string) copcodes = char_sequence.get_opcodes() obuffer, nbuffer = [], [] @@ -343,36 +328,36 @@ def tokens_diff(old_tokens, new_tokens, use_diff_match_patch=True): l = len(rep) if op == 0: for i, c in enumerate(rep): - obuffer.append((old_char_tokens[a+i][0], '', c)) - nbuffer.append((new_char_tokens[b+i][0], '', c)) + obuffer.append((old_char_tokens[a + i][0], "", c)) + nbuffer.append((new_char_tokens[b + i][0], "", c)) a += l b += l elif op == -1: for i, c in enumerate(rep): - obuffer.append((old_char_tokens[a+i][0], 'del', int_convert(c))) + obuffer.append((old_char_tokens[a + i][0], "del", int_convert(c))) a += l elif op == 1: for i, c in enumerate(rep): - nbuffer.append((new_char_tokens[b+i][0], 'ins', int_convert(c))) + nbuffer.append((new_char_tokens[b + i][0], "ins", int_convert(c))) b += l else: for ctag, co1, co2, cn1, cn2 in copcodes: - if ctag == 'equal': + if ctag == "equal": for token_class, token_text in old_char_tokens[co1:co2]: - obuffer.append((token_class, '', token_text)) + obuffer.append((token_class, "", token_text)) for token_class, token_text in new_char_tokens[cn1:cn2]: - nbuffer.append((token_class, '', token_text)) - elif ctag == 'delete': + nbuffer.append((token_class, "", token_text)) + elif ctag == "delete": for token_class, token_text in old_char_tokens[co1:co2]: - obuffer.append((token_class, 'del', int_convert(token_text))) - elif ctag == 'insert': + obuffer.append((token_class, "del", int_convert(token_text))) + elif ctag == "insert": for token_class, token_text in new_char_tokens[cn1:cn2]: - nbuffer.append((token_class, 'ins', int_convert(token_text))) - elif ctag == 'replace': + nbuffer.append((token_class, "ins", int_convert(token_text))) + elif ctag == "replace": for token_class, token_text in old_char_tokens[co1:co2]: - obuffer.append((token_class, 'del', int_convert(token_text))) + obuffer.append((token_class, "del", int_convert(token_text))) for token_class, token_text in new_char_tokens[cn1:cn2]: - nbuffer.append((token_class, 'ins', int_convert(token_text))) + nbuffer.append((token_class, "ins", int_convert(token_text))) old_tokens_result.extend(obuffer) new_tokens_result.extend(nbuffer) @@ -382,9 +367,8 @@ def tokens_diff(old_tokens, new_tokens, use_diff_match_patch=True): def diffset_node_getter(commit): def get_diff_node(file_name): - try: - return commit.get_node(file_name, pre_load=['size', 'flags', 'data']) + return commit.get_node(file_name, pre_load=["size", "flags", "data"]) except NodeDoesNotExistError: return None @@ -397,26 +381,26 @@ class DiffSet(object): adding highlighting, side by side/unified renderings and line diffs """ - HL_REAL = 'REAL' # highlights using original file, slow - HL_FAST = 'FAST' # highlights using just the line, fast but not correct - # in the case of multiline code - HL_NONE = 'NONE' # no highlighting, fastest - - def __init__(self, highlight_mode=HL_REAL, repo_name=None, - source_repo_name=None, - source_node_getter=lambda filename: None, - target_repo_name=None, - target_node_getter=lambda filename: None, - source_nodes=None, target_nodes=None, - # files over this size will use fast highlighting - max_file_size_limit=150 * 1024, - ): + HL_REAL = "REAL" # highlights using original file, slow + HL_FAST = "FAST" # highlights using just the line, fast but not correct + # in the case of multiline code + HL_NONE = "NONE" # no highlighting, fastest + def __init__( + self, + highlight_mode=HL_REAL, + repo_name=None, + source_repo_name=None, + source_node_getter=lambda filename: None, + target_repo_name=None, + target_node_getter=lambda filename: None, + source_nodes=None, + target_nodes=None, + # files over this size will use fast highlighting + max_file_size_limit=150 * 1024, + ): self.highlight_mode = highlight_mode - self.highlighted_filenodes = { - 'before': {}, - 'after': {} - } + self.highlighted_filenodes = {"before": {}, "after": {}} self.source_node_getter = source_node_getter self.target_node_getter = target_node_getter self.source_nodes = source_nodes or {} @@ -427,34 +411,38 @@ class DiffSet(object): self.max_file_size_limit = max_file_size_limit def render_patchset(self, patchset, source_ref=None, target_ref=None): - diffset = AttributeDict(dict( - lines_added=0, - lines_deleted=0, - changed_files=0, - files=[], - file_stats={}, - limited_diff=isinstance(patchset, LimitedDiffContainer), - repo_name=self.repo_name, - target_repo_name=self.target_repo_name, - source_repo_name=self.source_repo_name, - source_ref=source_ref, - target_ref=target_ref, - )) + diffset = AttributeDict( + dict( + lines_added=0, + lines_deleted=0, + changed_files=0, + files=[], + file_stats={}, + limited_diff=isinstance(patchset, LimitedDiffContainer), + repo_name=self.repo_name, + target_repo_name=self.target_repo_name, + source_repo_name=self.source_repo_name, + source_ref=source_ref, + target_ref=target_ref, + ) + ) for patch in patchset: - diffset.file_stats[patch['filename']] = patch['stats'] + diffset.file_stats[patch["filename"]] = patch["stats"] filediff = self.render_patch(patch) - filediff.diffset = StrictAttributeDict(dict( - source_ref=diffset.source_ref, - target_ref=diffset.target_ref, - repo_name=diffset.repo_name, - source_repo_name=diffset.source_repo_name, - target_repo_name=diffset.target_repo_name, - )) + filediff.diffset = StrictAttributeDict( + dict( + source_ref=diffset.source_ref, + target_ref=diffset.target_ref, + repo_name=diffset.repo_name, + source_repo_name=diffset.source_repo_name, + target_repo_name=diffset.target_repo_name, + ) + ) diffset.files.append(filediff) diffset.changed_files += 1 - if not patch['stats']['binary']: - diffset.lines_added += patch['stats']['added'] - diffset.lines_deleted += patch['stats']['deleted'] + if not patch["stats"]["binary"]: + diffset.lines_added += patch["stats"]["added"] + diffset.lines_deleted += patch["stats"]["deleted"] return diffset @@ -468,37 +456,33 @@ class DiffSet(object): extension = filenode.extension else: lexer = FileNode.get_lexer(filename=filename) - extension = filename.split('.')[-1] + extension = filename.split(".")[-1] lexer = get_custom_lexer(extension) or lexer self._lexer_cache[filename] = lexer return self._lexer_cache[filename] def render_patch(self, patch): - log.debug('rendering diff for %r', patch['filename']) + log.debug("rendering diff for %r", patch["filename"]) - source_filename = patch['original_filename'] - source_filename_bytes = patch['original_filename_bytes'] - target_filename = patch['filename'] - target_filename_bytes = patch['filename_bytes'] + source_filename = patch["original_filename"] + source_filename_bytes = patch["original_filename_bytes"] + target_filename = patch["filename"] + target_filename_bytes = patch["filename_bytes"] source_lexer = plain_text_lexer target_lexer = plain_text_lexer - if not patch['stats']['binary']: - node_hl_mode = self.HL_NONE if patch['chunks'] == [] else None + if not patch["stats"]["binary"]: + node_hl_mode = self.HL_NONE if patch["chunks"] == [] else None hl_mode = node_hl_mode or self.highlight_mode if hl_mode == self.HL_REAL: - if (source_filename and patch['operation'] in ('D', 'M') - and source_filename not in self.source_nodes): - self.source_nodes[source_filename] = ( - self.source_node_getter(source_filename_bytes)) + if source_filename and patch["operation"] in ("D", "M") and source_filename not in self.source_nodes: + self.source_nodes[source_filename] = self.source_node_getter(source_filename_bytes) - if (target_filename and patch['operation'] in ('A', 'M') - and target_filename not in self.target_nodes): - self.target_nodes[target_filename] = ( - self.target_node_getter(target_filename_bytes)) + if target_filename and patch["operation"] in ("A", "M") and target_filename not in self.target_nodes: + self.target_nodes[target_filename] = self.target_node_getter(target_filename_bytes) elif hl_mode == self.HL_FAST: source_lexer = self._get_lexer_for_filename(source_filename) @@ -506,7 +490,7 @@ class DiffSet(object): source_file = self.source_nodes.get(source_filename, source_filename) target_file = self.target_nodes.get(target_filename, target_filename) - raw_id_uid = '' + raw_id_uid = "" if self.source_nodes.get(source_filename): raw_id_uid = self.source_nodes[source_filename].commit.raw_id @@ -521,45 +505,47 @@ class DiffSet(object): # done can allow caching a lexer for a filenode to avoid the file lookup if isinstance(source_file, FileNode): source_filenode = source_file - #source_lexer = source_file.lexer + # source_lexer = source_file.lexer source_lexer = self._get_lexer_for_filename(source_filename) source_file.lexer = source_lexer if isinstance(target_file, FileNode): target_filenode = target_file - #target_lexer = target_file.lexer + # target_lexer = target_file.lexer target_lexer = self._get_lexer_for_filename(target_filename) target_file.lexer = target_lexer source_file_path, target_file_path = None, None - if source_filename != '/dev/null': + if source_filename != "/dev/null": source_file_path = source_filename - if target_filename != '/dev/null': + if target_filename != "/dev/null": target_file_path = target_filename source_file_type = source_lexer.name target_file_type = target_lexer.name - filediff = AttributeDict({ - 'source_file_path': source_file_path, - 'target_file_path': target_file_path, - 'source_filenode': source_filenode, - 'target_filenode': target_filenode, - 'source_file_type': target_file_type, - 'target_file_type': source_file_type, - 'patch': {'filename': patch['filename'], 'stats': patch['stats']}, - 'operation': patch['operation'], - 'source_mode': patch['stats']['old_mode'], - 'target_mode': patch['stats']['new_mode'], - 'limited_diff': patch['is_limited_diff'], - 'hunks': [], - 'hunk_ops': None, - 'diffset': self, - 'raw_id': raw_id_uid, - }) + filediff = AttributeDict( + { + "source_file_path": source_file_path, + "target_file_path": target_file_path, + "source_filenode": source_filenode, + "target_filenode": target_filenode, + "source_file_type": target_file_type, + "target_file_type": source_file_type, + "patch": {"filename": patch["filename"], "stats": patch["stats"]}, + "operation": patch["operation"], + "source_mode": patch["stats"]["old_mode"], + "target_mode": patch["stats"]["new_mode"], + "limited_diff": patch["is_limited_diff"], + "hunks": [], + "hunk_ops": None, + "diffset": self, + "raw_id": raw_id_uid, + } + ) - file_chunks = patch['chunks'][1:] + file_chunks = patch["chunks"][1:] for i, hunk in enumerate(file_chunks, 1): hunkbit = self.parse_hunk(hunk, source_file, target_file) @@ -572,22 +558,23 @@ class DiffSet(object): # this allows commenting on those if not file_chunks: actions = [] - for op_id, op_text in list(filediff.patch['stats']['ops'].items()): + for op_id, op_text in list(filediff.patch["stats"]["ops"].items()): if op_id == DEL_FILENODE: - actions.append('file was removed') + actions.append("file was removed") elif op_id == BIN_FILENODE: - actions.append('binary diff hidden') + actions.append("binary diff hidden") else: actions.append(safe_str(op_text)) - action_line = 'NO CONTENT: ' + \ - ', '.join(actions) or 'UNDEFINED_ACTION' + action_line = "NO CONTENT: " + ", ".join(actions) or "UNDEFINED_ACTION" - hunk_ops = {'source_length': 0, 'source_start': 0, - 'lines': [ - {'new_lineno': 0, 'old_lineno': 1, - 'action': 'unmod-no-hl', 'line': action_line} - ], - 'section_header': '', 'target_start': 1, 'target_length': 1} + hunk_ops = { + "source_length": 0, + "source_start": 0, + "lines": [{"new_lineno": 0, "old_lineno": 1, "action": "unmod-no-hl", "line": action_line}], + "section_header": "", + "target_start": 1, + "target_length": 1, + } hunkbit = self.parse_hunk(hunk_ops, source_file, target_file) hunkbit.source_file_path = source_file_path @@ -596,38 +583,38 @@ class DiffSet(object): return filediff def parse_hunk(self, hunk, source_file, target_file): - - result = AttributeDict(dict( - source_start=hunk['source_start'], - source_length=hunk['source_length'], - target_start=hunk['target_start'], - target_length=hunk['target_length'], - section_header=safe_str(hunk['section_header']), - lines=[], - )) + result = AttributeDict( + dict( + source_start=hunk["source_start"], + source_length=hunk["source_length"], + target_start=hunk["target_start"], + target_length=hunk["target_length"], + section_header=safe_str(hunk["section_header"]), + lines=[], + ) + ) before, after = [], [] - for line in hunk['lines']: - - if line['action'] in ['unmod', 'unmod-no-hl']: - no_hl = line['action'] == 'unmod-no-hl' + for line in hunk["lines"]: + if line["action"] in ["unmod", "unmod-no-hl"]: + no_hl = line["action"] == "unmod-no-hl" parsed_lines = self.parse_lines(before, after, source_file, target_file, no_hl=no_hl) result.lines.extend(parsed_lines) after.append(line) before.append(line) - elif line['action'] == 'add': + elif line["action"] == "add": after.append(line) - elif line['action'] == 'del': + elif line["action"] == "del": before.append(line) - elif line['action'] == 'old-no-nl': + elif line["action"] == "old-no-nl": before.append(line) - #line['line'] = safe_str(line['line']) - elif line['action'] == 'new-no-nl': - #line['line'] = safe_str(line['line']) + # line['line'] = safe_str(line['line']) + elif line["action"] == "new-no-nl": + # line['line'] = safe_str(line['line']) after.append(line) - all_actions = [x['action'] for x in after] + [x['action'] for x in before] - no_hl = {x for x in all_actions} == {'unmod-no-hl'} + all_actions = [x["action"] for x in after] + [x["action"] for x in before] + no_hl = {x for x in all_actions} == {"unmod-no-hl"} parsed_no_hl_lines = self.parse_lines(before, after, source_file, target_file, no_hl=no_hl) result.lines.extend(parsed_no_hl_lines) @@ -637,8 +624,7 @@ class DiffSet(object): return result - def parse_lines(self, before_lines, after_lines, source_file, target_file, - no_hl=False): + def parse_lines(self, before_lines, after_lines, source_file, target_file, no_hl=False): # TODO: dan: investigate doing the diff comparison and fast highlighting # on the entire before and after buffered block lines rather than by # line, this means we can get better 'fast' highlighting if the context @@ -651,19 +637,17 @@ class DiffSet(object): before_newline = AttributeDict() after_newline = AttributeDict() - if before_lines and before_lines[-1]['action'] == 'old-no-nl': + if before_lines and before_lines[-1]["action"] == "old-no-nl": before_newline_line = before_lines.pop(-1) - before_newline.content = '\n {}'.format( - render_tokenstream( - [(x[0], '', safe_str(x[1])) - for x in [('nonl', before_newline_line['line'])]])) + before_newline.content = "\n {}".format( + render_tokenstream([(x[0], "", safe_str(x[1])) for x in [("nonl", before_newline_line["line"])]]) + ) - if after_lines and after_lines[-1]['action'] == 'new-no-nl': + if after_lines and after_lines[-1]["action"] == "new-no-nl": after_newline_line = after_lines.pop(-1) - after_newline.content = '\n {}'.format( - render_tokenstream( - [(x[0], '', safe_str(x[1])) - for x in [('nonl', after_newline_line['line'])]])) + after_newline.content = "\n {}".format( + render_tokenstream([(x[0], "", safe_str(x[1])) for x in [("nonl", after_newline_line["line"])]]) + ) while before_lines or after_lines: before, after = None, None @@ -678,44 +662,48 @@ class DiffSet(object): modified = AttributeDict() if before: - if before['action'] == 'old-no-nl': - before_tokens = [('nonl', safe_str(before['line']))] + if before["action"] == "old-no-nl": + before_tokens = [("nonl", safe_str(before["line"]))] else: before_tokens = self.get_line_tokens( - line_text=before['line'], line_number=before['old_lineno'], - input_file=source_file, no_hl=no_hl, source='before') - original.lineno = before['old_lineno'] - original.content = before['line'] - original.action = self.action_to_op(before['action']) + line_text=before["line"], + line_number=before["old_lineno"], + input_file=source_file, + no_hl=no_hl, + source="before", + ) + original.lineno = before["old_lineno"] + original.content = before["line"] + original.action = self.action_to_op(before["action"]) - original.get_comment_args = ( - source_file, 'o', before['old_lineno']) + original.get_comment_args = (source_file, "o", before["old_lineno"]) if after: - if after['action'] == 'new-no-nl': - after_tokens = [('nonl', safe_str(after['line']))] + if after["action"] == "new-no-nl": + after_tokens = [("nonl", safe_str(after["line"]))] else: after_tokens = self.get_line_tokens( - line_text=after['line'], line_number=after['new_lineno'], - input_file=target_file, no_hl=no_hl, source='after') - modified.lineno = after['new_lineno'] - modified.content = after['line'] - modified.action = self.action_to_op(after['action']) + line_text=after["line"], + line_number=after["new_lineno"], + input_file=target_file, + no_hl=no_hl, + source="after", + ) + modified.lineno = after["new_lineno"] + modified.content = after["line"] + modified.action = self.action_to_op(after["action"]) - modified.get_comment_args = (target_file, 'n', after['new_lineno']) + modified.get_comment_args = (target_file, "n", after["new_lineno"]) # diff the lines if before_tokens and after_tokens: - o_tokens, m_tokens, similarity = tokens_diff( - before_tokens, after_tokens) + o_tokens, m_tokens, similarity = tokens_diff(before_tokens, after_tokens) original.content = render_tokenstream(o_tokens) modified.content = render_tokenstream(m_tokens) elif before_tokens: - original.content = render_tokenstream( - [(x[0], '', x[1]) for x in before_tokens]) + original.content = render_tokenstream([(x[0], "", x[1]) for x in before_tokens]) elif after_tokens: - modified.content = render_tokenstream( - [(x[0], '', x[1]) for x in after_tokens]) + modified.content = render_tokenstream([(x[0], "", x[1]) for x in after_tokens]) if not before_lines and before_newline: original.content += before_newline.content @@ -724,14 +712,18 @@ class DiffSet(object): modified.content += after_newline.content after_newline = None - lines.append(AttributeDict({ - 'original': original, - 'modified': modified, - })) + lines.append( + AttributeDict( + { + "original": original, + "modified": modified, + } + ) + ) return lines - def get_line_tokens(self, line_text, line_number, input_file=None, no_hl=False, source=''): + def get_line_tokens(self, line_text, line_number, input_file=None, no_hl=False, source=""): filenode = None filename = None @@ -754,7 +746,7 @@ class DiffSet(object): return list(tokenize_string(line_text, plain_text_lexer)) - def get_tokenized_filenode_line(self, filenode, line_number, lexer=None, source=''): + def get_tokenized_filenode_line(self, filenode, line_number, lexer=None, source=""): name_hash = hash(filenode) hl_node_code = self.highlighted_filenodes[source] @@ -765,54 +757,71 @@ class DiffSet(object): try: return hl_node_code[name_hash][line_number - 1] except Exception: - log.exception('diff rendering error on L:%s and file=%s', line_number - 1, filenode.name) - return [('', 'L{}: rhodecode diff rendering error'.format(line_number))] + log.exception("diff rendering error on L:%s and file=%s", line_number - 1, filenode.name) + return [("", "L{}: rhodecode diff rendering error".format(line_number))] def action_to_op(self, action): return { - 'add': '+', - 'del': '-', - 'unmod': ' ', - 'unmod-no-hl': ' ', - 'old-no-nl': ' ', - 'new-no-nl': ' ', + "add": "+", + "del": "-", + "unmod": " ", + "unmod-no-hl": " ", + "old-no-nl": " ", + "new-no-nl": " ", }.get(action, action) def as_unified(self, lines): """ Return a generator that yields the lines of a diff in unified order """ + def generator(): buf = [] for line in lines: - - if buf and not line.original or line.original.action == ' ': + if buf and not line.original or line.original.action == " ": yield from buf buf = [] if line.original: - if line.original.action == ' ': - yield (line.original.lineno, line.modified.lineno, - line.original.action, line.original.content, - line.original.get_comment_args) + if line.original.action == " ": + yield ( + line.original.lineno, + line.modified.lineno, + line.original.action, + line.original.content, + line.original.get_comment_args, + ) continue - if line.original.action == '-': - yield (line.original.lineno, None, - line.original.action, line.original.content, - line.original.get_comment_args) + if line.original.action == "-": + yield ( + line.original.lineno, + None, + line.original.action, + line.original.content, + line.original.get_comment_args, + ) - if line.modified.action == '+': - buf.append(( - None, line.modified.lineno, - line.modified.action, line.modified.content, - line.modified.get_comment_args)) + if line.modified.action == "+": + buf.append( + ( + None, + line.modified.lineno, + line.modified.action, + line.modified.content, + line.modified.get_comment_args, + ) + ) continue if line.modified: - yield (None, line.modified.lineno, - line.modified.action, line.modified.content, - line.modified.get_comment_args) + yield ( + None, + line.modified.lineno, + line.modified.action, + line.modified.content, + line.modified.get_comment_args, + ) yield from buf diff --git a/rhodecode/lib/colander_utils.py b/rhodecode/lib/colander_utils.py index 7f3e3280..7e6f5fc5 100644 --- a/rhodecode/lib/colander_utils.py +++ b/rhodecode/lib/colander_utils.py @@ -23,6 +23,6 @@ def strip_whitespace(value): Implements the `colander.interface.Preparer` interface. """ if isinstance(value, str): - return value.strip(' \t\n\r') + return value.strip(" \t\n\r") else: return value diff --git a/rhodecode/lib/colored_formatter.py b/rhodecode/lib/colored_formatter.py index 2569f630..fcf55f56 100644 --- a/rhodecode/lib/colored_formatter.py +++ b/rhodecode/lib/colored_formatter.py @@ -35,15 +35,12 @@ def _deprecated_formatter(name): BaseFormatter = getattr(logging_formatter, name) class LegacyFormatter(BaseFormatter): - def __init__(self, *args, **kwargs): - warnings.warn( - "Use rhodecode.lib.logging_formatter.%s instead." % name, - DeprecationWarning) + warnings.warn("Use rhodecode.lib.logging_formatter.%s instead." % name, DeprecationWarning) BaseFormatter.__init__(self, *args, **kwargs) return LegacyFormatter -ColorFormatter = _deprecated_formatter('ColorFormatter') -ColorFormatterSql = _deprecated_formatter('ColorFormatterSql') +ColorFormatter = _deprecated_formatter("ColorFormatter") +ColorFormatterSql = _deprecated_formatter("ColorFormatterSql") diff --git a/rhodecode/lib/config_utils.py b/rhodecode/lib/config_utils.py index c93b97af..b53ee855 100644 --- a/rhodecode/lib/config_utils.py +++ b/rhodecode/lib/config_utils.py @@ -20,6 +20,7 @@ import os def get_config(ini_path, **kwargs): import configparser + parser = configparser.ConfigParser(**kwargs) parser.read(ini_path) return parser @@ -27,9 +28,9 @@ def get_config(ini_path, **kwargs): def get_app_config_lightweight(ini_path): parser = get_config(ini_path) - parser.set('app:main', 'here', os.getcwd()) - parser.set('app:main', '__file__', ini_path) - return dict(parser.items('app:main')) + parser.set("app:main", "here", os.getcwd()) + parser.set("app:main", "__file__", ini_path) + return dict(parser.items("app:main")) def get_app_config(ini_path): @@ -37,4 +38,5 @@ def get_app_config(ini_path): This loads the app context and provides a heavy type iniliaziation of config """ from paste.deploy.loadwsgi import appconfig - return appconfig(f'config:{ini_path}', relative_to=os.getcwd()) + + return appconfig(f"config:{ini_path}", relative_to=os.getcwd()) diff --git a/rhodecode/lib/datelib.py b/rhodecode/lib/datelib.py index d53e1960..a00cb257 100644 --- a/rhodecode/lib/datelib.py +++ b/rhodecode/lib/datelib.py @@ -48,7 +48,7 @@ def date_astimestamp(value): """ Convert a given `datetime.datetime` into a `float` like `time.time` """ - return time.mktime(value.timetuple()) + value.microsecond / 1E6 + return time.mktime(value.timetuple()) + value.microsecond / 1e6 def date_to_timestamp_plus_offset(value): @@ -60,8 +60,7 @@ def date_to_timestamp_plus_offset(value): if value is None: value = time.time() elif isinstance(value, datetime.datetime): - assert not is_aware(value), ( - "This code is not prepared to handle aware datetime instances") + assert not is_aware(value), "This code is not prepared to handle aware datetime instances" value = date_astimestamp(value) return value, time.timezone @@ -73,5 +72,4 @@ def is_aware(value): The logic is described in Python's docs: http://docs.python.org/library/datetime.html#datetime.tzinfo """ - return (value.tzinfo is not None - and value.tzinfo.utcoffset(value) is not None) + return value.tzinfo is not None and value.tzinfo.utcoffset(value) is not None diff --git a/rhodecode/lib/db_manage.py b/rhodecode/lib/db_manage.py index fcf97177..4f578756 100644 --- a/rhodecode/lib/db_manage.py +++ b/rhodecode/lib/db_manage.py @@ -170,9 +170,7 @@ class DbManage(object): ) upgrade = self.ask_ok( - "You are about to perform a database upgrade. Make " - "sure you have backed up your database. " - "Continue ? [y/n]" + "You are about to perform a database upgrade. Make sure you have backed up your database. Continue ? [y/n]" ) if not upgrade: log.info("No upgrade performed") @@ -186,11 +184,11 @@ class DbManage(object): try: curr_version = api.db_version(db_uri, repository_path) - msg = f"Found current database db_uri under version " f"control with version {curr_version}" + msg = f"Found current database db_uri under version control with version {curr_version}" except (RuntimeError, DatabaseNotControlledError): curr_version = 1 - msg = f"Current database is not under version control. " f"Setting as version {curr_version}" + msg = f"Current database is not under version control. Setting as version {curr_version}" api.version_control(db_uri, repository_path, curr_version) notify(msg) @@ -200,7 +198,7 @@ class DbManage(object): sys.exit(0) upgrade_steps = list(range(curr_version + 1, __dbversion__ + 1)) - notify(f"attempting to upgrade database from " f"version {curr_version} to version {__dbversion__}") + notify(f"attempting to upgrade database from version {curr_version} to version {__dbversion__}") # CALL THE PROPER ORDER OF STEPS TO PERFORM FULL UPGRADE final_step = "latest" @@ -287,7 +285,7 @@ class DbManage(object): self.create_user(username, password, email, True, strict_creation_check=False, api_key=api_key) def _get_admin_password(self): - password = getpass.getpass("Specify admin password " "(min 6 chars):") + password = getpass.getpass("Specify admin password (min 6 chars):") confirm = getpass.getpass("Confirm password:") if password != confirm: @@ -509,7 +507,7 @@ class DbManage(object): elif not os.access(path, os.W_OK) and path_ok: log.warning("No write permission to given path %s", path) - q = f"Given path {path} is not writeable, do you want to " f"continue with read only mode ? [y/n]" + q = f"Given path {path} is not writeable, do you want to continue with read only mode ? [y/n]" if not self.ask_ok(q): log.error("Canceled by user") sys.exit(-1) @@ -523,7 +521,7 @@ class DbManage(object): real_path = os.path.normpath(os.path.realpath(path)) if real_path != os.path.normpath(path): - q = f"Path looks like a symlink, RhodeCode Enterprise will store " f"given path as {real_path} ? [y/n]" + q = f"Path looks like a symlink, RhodeCode Enterprise will store given path as {real_path} ? [y/n]" if not self.ask_ok(q): log.error("Canceled by user") sys.exit(-1) diff --git a/rhodecode/lib/dbmigrate/migrate/__init__.py b/rhodecode/lib/dbmigrate/migrate/__init__.py index a3dc26ab..3aa62a94 100644 --- a/rhodecode/lib/dbmigrate/migrate/__init__.py +++ b/rhodecode/lib/dbmigrate/migrate/__init__.py @@ -1,11 +1,11 @@ """ - SQLAlchemy migrate provides two APIs :mod:`migrate.versioning` for - database schema version and repository management and - :mod:`migrate.changeset` that allows to define database schema changes - using Python. +SQLAlchemy migrate provides two APIs :mod:`migrate.versioning` for +database schema version and repository management and +:mod:`migrate.changeset` that allows to define database schema changes +using Python. """ from rhodecode.lib.dbmigrate.migrate.versioning import * from rhodecode.lib.dbmigrate.migrate.changeset import * -__version__ = '0.11.0' +__version__ = "0.11.0" diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/__init__.py b/rhodecode/lib/dbmigrate/migrate/changeset/__init__.py index 0d297fbb..3d50d239 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/__init__.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/__init__.py @@ -1,9 +1,10 @@ """ - This module extends SQLAlchemy and provides additional DDL [#]_ - support. +This module extends SQLAlchemy and provides additional DDL [#]_ +support. - .. [#] SQL Data Definition Language +.. [#] SQL Data Definition Language """ + import re import warnings diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/ansisql.py b/rhodecode/lib/dbmigrate/migrate/changeset/ansisql.py index 40e10d17..056fcfd9 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/ansisql.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/ansisql.py @@ -1,20 +1,17 @@ """ - Extensions to SQLAlchemy for altering existing tables. +Extensions to SQLAlchemy for altering existing tables. - At the moment, this isn't so much based off of ANSI as much as - things that just happen to work with multiple databases. +At the moment, this isn't so much based off of ANSI as much as +things that just happen to work with multiple databases. """ + import io import sqlalchemy as sa from sqlalchemy.schema import SchemaVisitor from sqlalchemy.engine.default import DefaultDialect from sqlalchemy.sql import ClauseElement -from sqlalchemy.schema import (ForeignKeyConstraint, - PrimaryKeyConstraint, - CheckConstraint, - UniqueConstraint, - Index) +from sqlalchemy.schema import ForeignKeyConstraint, PrimaryKeyConstraint, CheckConstraint, UniqueConstraint, Index import sqlalchemy.sql.compiler from rhodecode.lib.dbmigrate.migrate import exceptions @@ -23,6 +20,7 @@ from rhodecode.lib.dbmigrate.migrate.changeset import util from sqlalchemy.schema import AddConstraint, DropConstraint from sqlalchemy.sql.compiler import DDLCompiler + SchemaGenerator = SchemaDropper = DDLCompiler @@ -79,7 +77,7 @@ class AlterTableVisitor(SchemaVisitor): or string (table name) """ table = self._to_table(param) - self.append('\nALTER TABLE %s ' % self.preparer.format_table(table)) + self.append("\nALTER TABLE %s " % self.preparer.format_table(table)) return table @@ -107,10 +105,9 @@ class ANSIColumnGenerator(AlterTableVisitor, SchemaGenerator): # add indexes and unique constraints if column.index_name: - Index(column.index_name,column).create() + Index(column.index_name, column).create() elif column.unique_name: - constraint.UniqueConstraint(column, - name=column.unique_name).create() + constraint.UniqueConstraint(column, name=column.unique_name).create() # SA bounds FK constraints to table, add manually for fk in column.foreign_keys: @@ -118,13 +115,13 @@ class ANSIColumnGenerator(AlterTableVisitor, SchemaGenerator): # add primary key constraint if needed if column.primary_key_name: - cons = constraint.PrimaryKeyConstraint(column, - name=column.primary_key_name) + cons = constraint.PrimaryKeyConstraint(column, name=column.primary_key_name) cons.create() def add_foreignkey(self, fk): self.connection.execute(AddConstraint(fk)) + class ANSIColumnDropper(AlterTableVisitor, SchemaDropper): """Extends ANSI SQL dropper for column dropping (``ALTER TABLE DROP COLUMN``). @@ -137,7 +134,7 @@ class ANSIColumnDropper(AlterTableVisitor, SchemaDropper): :type column: :class:`sqlalchemy.Column` """ table = self.start_alter_table(column) - self.append('DROP COLUMN %s' % self.preparer.format_column(column)) + self.append("DROP COLUMN %s" % self.preparer.format_column(column)) self.execute() @@ -165,40 +162,42 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator): def visit_index(self, index): """Rename an index""" - if hasattr(self, '_validate_identifier'): + if hasattr(self, "_validate_identifier"): # SA <= 0.6.3 - self.append("ALTER INDEX %s RENAME TO %s" % ( - self.preparer.quote( - self._validate_identifier( - index.name, True), index.quote), - self.preparer.quote( - self._validate_identifier( - index.new_name, True), index.quote))) - elif hasattr(self, '_index_identifier'): + self.append( + "ALTER INDEX %s RENAME TO %s" + % ( + self.preparer.quote(self._validate_identifier(index.name, True), index.quote), + self.preparer.quote(self._validate_identifier(index.new_name, True), index.quote), + ) + ) + elif hasattr(self, "_index_identifier"): # SA >= 0.6.5, < 0.8 - self.append("ALTER INDEX %s RENAME TO %s" % ( - self.preparer.quote( - self._index_identifier( - index.name), index.quote), - self.preparer.quote( - self._index_identifier( - index.new_name), index.quote))) + self.append( + "ALTER INDEX %s RENAME TO %s" + % ( + self.preparer.quote(self._index_identifier(index.name), index.quote), + self.preparer.quote(self._index_identifier(index.new_name), index.quote), + ) + ) else: # SA >= 0.8 class NewName(object): """Map obj.name -> obj.new_name""" + def __init__(self, index): self.name = index.new_name self._obj = index def __getattr__(self, attr): - if attr == 'name': + if attr == "name": return getattr(self, attr) return getattr(self._obj, attr) - self.append("ALTER INDEX %s RENAME TO %s" % ( - self._prepared_index_name(index), - self._prepared_index_name(NewName(index)))) + self.append( + "ALTER INDEX %s RENAME TO %s" + % (self._prepared_index_name(index), self._prepared_index_name(NewName(index))) + ) self.execute() @@ -206,15 +205,15 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator): """Rename/change a column.""" # ALTER COLUMN is implemented as several ALTER statements keys = list(delta.keys()) - if 'type' in keys: + if "type" in keys: self._run_subvisit(delta, self._visit_column_type) - if 'nullable' in keys: + if "nullable" in keys: self._run_subvisit(delta, self._visit_column_nullable) - if 'server_default' in keys: + if "server_default" in keys: # Skip 'default': only handle server-side defaults, others # are managed by the app, not the db. self._run_subvisit(delta, self._visit_column_default) - if 'name' in keys: + if "name" in keys: self._run_subvisit(delta, self._visit_column_name, start_alter=False) def _run_subvisit(self, delta, func, start_alter=True): @@ -233,7 +232,7 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator): self.append("ALTER COLUMN %s " % self.preparer.quote(col_name, q)) def _visit_column_nullable(self, table, column, delta): - nullable = delta['nullable'] + nullable = delta["nullable"] if nullable: self.append("DROP NOT NULL") else: @@ -247,7 +246,7 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator): self.append("DROP DEFAULT") def _visit_column_type(self, table, column, delta): - type_ = delta['type'] + type_ = delta["type"] type_text = str(type_.compile(dialect=self.dialect)) self.append("TYPE %s" % type_text) @@ -256,7 +255,7 @@ class ANSISchemaChanger(AlterTableVisitor, SchemaGenerator): q = util.safe_quote(table) col_name = self.preparer.quote(delta.current_name, q) new_name = self.preparer.format_column(delta.result_column) - self.append('RENAME COLUMN %s TO %s' % (col_name, new_name)) + self.append("RENAME COLUMN %s TO %s" % (col_name, new_name)) class ANSIConstraintCommon(AlterTableVisitor): @@ -293,12 +292,14 @@ class ANSIConstraintCommon(AlterTableVisitor): def visit_migrate_unique_constraint(self, *p, **k): self._visit_constraint(*p, **k) + class ANSIConstraintGenerator(ANSIConstraintCommon, SchemaGenerator): def _visit_constraint(self, constraint): constraint.name = self.get_constraint_name(constraint) self.append(self.process(AddConstraint(constraint))) self.execute() + class ANSIConstraintDropper(ANSIConstraintCommon, SchemaDropper): def _visit_constraint(self, constraint): constraint.name = self.get_constraint_name(constraint) diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/constraint.py b/rhodecode/lib/dbmigrate/migrate/changeset/constraint.py index 89b9902b..522f9983 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/constraint.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/constraint.py @@ -1,6 +1,7 @@ """ - This module defines standalone schema constraint classes. +This module defines standalone schema constraint classes. """ + from sqlalchemy import schema from rhodecode.lib.dbmigrate.migrate.exceptions import * @@ -19,16 +20,16 @@ class ConstraintChangeset(object): if col.table is not None and table is None: table = col.table if table_name: - col = '.'.join((col.table.name, col.name)) + col = ".".join((col.table.name, col.name)) else: col = col.name colnames.append(col) return colnames, table def __do_imports(self, visitor_name, *a, **kw): - engine = kw.pop('engine', self.table.bind) - from rhodecode.lib.dbmigrate.migrate.changeset.databases.visitor import ( - get_engine_visitor, run_single_visitor) + engine = kw.pop("engine", self.table.bind) + from rhodecode.lib.dbmigrate.migrate.changeset.databases.visitor import get_engine_visitor, run_single_visitor + visitorcallable = get_engine_visitor(engine, visitor_name) run_single_visitor(engine, visitorcallable, self, *a, **kw) @@ -42,7 +43,7 @@ class ConstraintChangeset(object): :type connection: :class:`sqlalchemy.engine.base.Connection` instance """ # TODO: set the parent here instead of in __init__ - self.__do_imports('constraintgenerator', *a, **kw) + self.__do_imports("constraintgenerator", *a, **kw) def drop(self, *a, **kw): """Drop the constraint from the database. @@ -56,12 +57,12 @@ class ConstraintChangeset(object): :type connection: :class:`sqlalchemy.engine.base.Connection` instance :returns: Instance with cleared columns """ - self.cascade = kw.pop('cascade', False) - self.__do_imports('constraintdropper', *a, **kw) + self.cascade = kw.pop("cascade", False) + self.__do_imports("constraintdropper", *a, **kw) # the spirit of Constraint objects is that they # are immutable (just like in a DB. they're only ADDed # or DROPped). - #self.columns.clear() + # self.columns.clear() return self @@ -76,11 +77,11 @@ class PrimaryKeyConstraint(ConstraintChangeset, schema.PrimaryKeyConstraint): :type cols: strings or Column instances """ - __migrate_visit_name__ = 'migrate_primary_key_constraint' + __migrate_visit_name__ = "migrate_primary_key_constraint" def __init__(self, *cols, **kwargs): colnames, table = self._normalize_columns(cols) - table = kwargs.pop('table', table) + table = kwargs.pop("table", table) super(PrimaryKeyConstraint, self).__init__(*colnames, **kwargs) if table is not None: self._set_parent(table) @@ -103,16 +104,13 @@ class ForeignKeyConstraint(ConstraintChangeset, schema.ForeignKeyConstraint): :type refcolumns: list of strings or Column instances """ - __migrate_visit_name__ = 'migrate_foreign_key_constraint' + __migrate_visit_name__ = "migrate_foreign_key_constraint" def __init__(self, columns, refcolumns, *args, **kwargs): colnames, table = self._normalize_columns(columns) - table = kwargs.pop('table', table) - refcolnames, reftable = self._normalize_columns(refcolumns, - table_name=True) - super(ForeignKeyConstraint, self).__init__( - colnames, refcolnames, *args, **kwargs - ) + table = kwargs.pop("table", table) + refcolnames, reftable = self._normalize_columns(refcolumns, table_name=True) + super(ForeignKeyConstraint, self).__init__(colnames, refcolnames, *args, **kwargs) if table is not None: self._set_parent(table) @@ -126,17 +124,19 @@ class ForeignKeyConstraint(ConstraintChangeset, schema.ForeignKeyConstraint): def autoname(self): """Mimic the database's automatic constraint names""" - if hasattr(self.columns, 'keys'): + if hasattr(self.columns, "keys"): # SA <= 0.5 firstcol = self.columns[list(self.columns.keys())[0]] ret = "%(table)s_%(firstcolumn)s_fkey" % { - 'table': firstcol.table.name, - 'firstcolumn': firstcol.name,} + "table": firstcol.table.name, + "firstcolumn": firstcol.name, + } else: # SA >= 0.6 ret = "%(table)s_%(firstcolumn)s_fkey" % { - 'table': self.table.name, - 'firstcolumn': self.columns[0],} + "table": self.table.name, + "firstcolumn": self.columns[0], + } return ret @@ -154,23 +154,21 @@ class CheckConstraint(ConstraintChangeset, schema.CheckConstraint): :type sqltext: string """ - __migrate_visit_name__ = 'migrate_check_constraint' + __migrate_visit_name__ = "migrate_check_constraint" def __init__(self, sqltext, *args, **kwargs): - cols = kwargs.pop('columns', []) - if not cols and not kwargs.get('name', False): - raise InvalidConstraintError('You must either set "name"' - 'parameter or "columns" to autogenarate it.') + cols = kwargs.pop("columns", []) + if not cols and not kwargs.get("name", False): + raise InvalidConstraintError('You must either set "name"parameter or "columns" to autogenarate it.') colnames, table = self._normalize_columns(cols) - table = kwargs.pop('table', table) + table = kwargs.pop("table", table) schema.CheckConstraint.__init__(self, sqltext, *args, **kwargs) if table is not None: self._set_parent(table) self.colnames = colnames def autoname(self): - return "%(table)s_%(cols)s_check" % \ - {'table': self.table.name, 'cols': "_".join(self.colnames)} + return "%(table)s_%(cols)s_check" % {"table": self.table.name, "cols": "_".join(self.colnames)} class UniqueConstraint(ConstraintChangeset, schema.UniqueConstraint): @@ -186,15 +184,15 @@ class UniqueConstraint(ConstraintChangeset, schema.UniqueConstraint): .. versionadded:: 0.6.0 """ - __migrate_visit_name__ = 'migrate_unique_constraint' + __migrate_visit_name__ = "migrate_unique_constraint" def __init__(self, *cols, **kwargs): self.colnames, table = self._normalize_columns(cols) - table = kwargs.pop('table', table) + table = kwargs.pop("table", table) super(UniqueConstraint, self).__init__(*self.colnames, **kwargs) if table is not None: self._set_parent(table) def autoname(self): """Mimic the database's automatic constraint names""" - return "%s_%s_key" % (self.table.name, '_'.join(self.colnames)) + return "%s_%s_key" % (self.table.name, "_".join(self.colnames)) diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/databases/__init__.py b/rhodecode/lib/dbmigrate/migrate/changeset/databases/__init__.py index 075a7870..19f03992 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/databases/__init__.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/__init__.py @@ -1,11 +1,12 @@ """ - This module contains database dialect specific changeset - implementations. +This module contains database dialect specific changeset +implementations. """ + __all__ = [ - 'postgres', - 'sqlite', - 'mysql', - 'oracle', - 'ibmdb2', + "postgres", + "sqlite", + "mysql", + "oracle", + "ibmdb2", ] diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/databases/firebird.py b/rhodecode/lib/dbmigrate/migrate/changeset/databases/firebird.py index ae0d7bfc..5409ec5d 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/databases/firebird.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/firebird.py @@ -1,6 +1,7 @@ """ - Firebird database specific implementations of changeset classes. +Firebird database specific implementations of changeset classes. """ + from sqlalchemy.databases import firebird as sa_base from sqlalchemy.schema import PrimaryKeyConstraint from rhodecode.lib.dbmigrate.migrate import exceptions @@ -9,6 +10,7 @@ from rhodecode.lib.dbmigrate.migrate.changeset import ansisql FBSchemaGenerator = sa_base.FBDDLCompiler + class FBColumnGenerator(FBSchemaGenerator, ansisql.ANSIColumnGenerator): """Firebird column generator implementation.""" @@ -33,7 +35,7 @@ class FBColumnDropper(ansisql.ANSIColumnDropper): # TODO: recreate index if it references more than this column for cons in column.table.constraints: - if isinstance(cons,PrimaryKeyConstraint): + if isinstance(cons, PrimaryKeyConstraint): # will be deleted only when the column its on # is deleted! continue @@ -47,7 +49,7 @@ class FBColumnDropper(ansisql.ANSIColumnDropper): # TODO: recreate unique constraint if it refenrences more than this column self.start_alter_table(column) - self.append('DROP %s' % self.preparer.format_column(column)) + self.append("DROP %s" % self.preparer.format_column(column)) self.execute() @@ -56,20 +58,18 @@ class FBSchemaChanger(ansisql.ANSISchemaChanger): def visit_table(self, table): """Rename table not supported""" - raise exceptions.NotSupportedError( - "Firebird does not support renaming tables.") + raise exceptions.NotSupportedError("Firebird does not support renaming tables.") def _visit_column_name(self, table, column, delta): self.start_alter_table(table) col_name = self.preparer.quote(delta.current_name, table.quote) new_name = self.preparer.format_column(delta.result_column) - self.append('ALTER COLUMN %s TO %s' % (col_name, new_name)) + self.append("ALTER COLUMN %s TO %s" % (col_name, new_name)) def _visit_column_nullable(self, table, column, delta): """Changing NULL is not supported""" # TODO: http://www.firebirdfaq.org/faq103/ - raise exceptions.NotSupportedError( - "Firebird does not support altering NULL bevahior.") + raise exceptions.NotSupportedError("Firebird does not support altering NULL bevahior.") class FBConstraintGenerator(ansisql.ANSIConstraintGenerator): @@ -81,8 +81,7 @@ class FBConstraintDropper(ansisql.ANSIConstraintDropper): def cascade_constraint(self, constraint): """Cascading constraints is not supported""" - raise exceptions.NotSupportedError( - "Firebird does not support cascading constraints") + raise exceptions.NotSupportedError("Firebird does not support cascading constraints") class FBDialect(ansisql.ANSIDialect): diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/databases/mysql.py b/rhodecode/lib/dbmigrate/migrate/changeset/databases/mysql.py index 7c5c016b..9e7398bd 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/databases/mysql.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/mysql.py @@ -1,5 +1,5 @@ """ - MySQL database specific implementations of changeset classes. +MySQL database specific implementations of changeset classes. """ import sqlalchemy @@ -11,9 +11,9 @@ from rhodecode.lib.dbmigrate.migrate.changeset import ansisql from rhodecode.lib.dbmigrate.migrate.changeset import util - MySQLSchemaGenerator = sa_base.MySQLDDLCompiler + class MySQLColumnGenerator(MySQLSchemaGenerator, ansisql.ANSIColumnGenerator): pass @@ -23,15 +23,15 @@ class MySQLColumnDropper(ansisql.ANSIColumnDropper): class MySQLSchemaChanger(MySQLSchemaGenerator, ansisql.ANSISchemaChanger): - def visit_column(self, delta): table = delta.table colspec = self.get_column_specification(delta.result_column) if delta.result_column.autoincrement: - primary_keys = [c for c in table.primary_key.columns - if (c.autoincrement and - isinstance(c.type, sqltypes.Integer) and - not c.foreign_keys)] + primary_keys = [ + c + for c in table.primary_key.columns + if (c.autoincrement and isinstance(c.type, sqltypes.Integer) and not c.foreign_keys) + ] if primary_keys: first = primary_keys.pop(0) @@ -57,8 +57,7 @@ class MySQLConstraintGenerator(ansisql.ANSIConstraintGenerator): class MySQLConstraintDropper(MySQLSchemaGenerator, ansisql.ANSIConstraintDropper): def visit_migrate_check_constraint(self, *p, **k): - raise exceptions.NotSupportedError("MySQL does not support CHECK" - " constraints, use triggers instead.") + raise exceptions.NotSupportedError("MySQL does not support CHECK constraints, use triggers instead.") class MySQLDialect(ansisql.ANSIDialect): diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/databases/oracle.py b/rhodecode/lib/dbmigrate/migrate/changeset/databases/oracle.py index 253d8a17..299d0892 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/databases/oracle.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/oracle.py @@ -1,6 +1,7 @@ """ - Oracle database specific implementations of changeset classes. +Oracle database specific implementations of changeset classes. """ + import sqlalchemy as sa from sqlalchemy.databases import oracle as sa_base @@ -20,15 +21,13 @@ class OracleColumnDropper(ansisql.ANSIColumnDropper): class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger): - def get_column_specification(self, column, **kwargs): # Ignore the NOT NULL generated - override_nullable = kwargs.pop('override_nullable', None) + override_nullable = kwargs.pop("override_nullable", None) if override_nullable: orig = column.nullable column.nullable = True - ret = super(OracleSchemaChanger, self).get_column_specification( - column, **kwargs) + ret = super(OracleSchemaChanger, self).get_column_specification(column, **kwargs) if override_nullable: column.nullable = orig return ret @@ -36,39 +35,32 @@ class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger): def visit_column(self, delta): keys = list(delta.keys()) - if 'name' in keys: - self._run_subvisit(delta, - self._visit_column_name, - start_alter=False) + if "name" in keys: + self._run_subvisit(delta, self._visit_column_name, start_alter=False) - if len(set(('type', 'nullable', 'server_default')).intersection(keys)): - self._run_subvisit(delta, - self._visit_column_change, - start_alter=False) + if len(set(("type", "nullable", "server_default")).intersection(keys)): + self._run_subvisit(delta, self._visit_column_change, start_alter=False) def _visit_column_change(self, table, column, delta): # Oracle cannot drop a default once created, but it can set it # to null. We'll do that if default=None # http://forums.oracle.com/forums/message.jspa?messageID=1273234#1273234 - dropdefault_hack = (column.server_default is None \ - and 'server_default' in list(delta.keys())) + dropdefault_hack = column.server_default is None and "server_default" in list(delta.keys()) # Oracle apparently doesn't like it when we say "not null" if # the column's already not null. Fudge it, so we don't need a # new function - notnull_hack = ((not column.nullable) \ - and ('nullable' not in list(delta.keys()))) + notnull_hack = (not column.nullable) and ("nullable" not in list(delta.keys())) # We need to specify NULL if we're removing a NOT NULL # constraint - null_hack = (column.nullable and ('nullable' in list(delta.keys()))) + null_hack = column.nullable and ("nullable" in list(delta.keys())) if dropdefault_hack: column.server_default = sa.PassiveDefault(sa.sql.null()) if notnull_hack: column.nullable = True - colspec = self.get_column_specification(column, - override_nullable=null_hack) + colspec = self.get_column_specification(column, override_nullable=null_hack) if null_hack: - colspec += ' NULL' + colspec += " NULL" if notnull_hack: column.nullable = False if dropdefault_hack: @@ -81,22 +73,18 @@ class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger): class OracleConstraintCommon(object): - def get_constraint_name(self, cons): # Oracle constraints can't guess their name like other DBs if not cons.name: - raise exceptions.NotSupportedError( - "Oracle constraint names must be explicitly stated") + raise exceptions.NotSupportedError("Oracle constraint names must be explicitly stated") return cons.name -class OracleConstraintGenerator(OracleConstraintCommon, - ansisql.ANSIConstraintGenerator): +class OracleConstraintGenerator(OracleConstraintCommon, ansisql.ANSIConstraintGenerator): pass -class OracleConstraintDropper(OracleConstraintCommon, - ansisql.ANSIConstraintDropper): +class OracleConstraintDropper(OracleConstraintCommon, ansisql.ANSIConstraintDropper): pass diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/databases/postgres.py b/rhodecode/lib/dbmigrate/migrate/changeset/databases/postgres.py index 9d8c81c0..474a1d66 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/databases/postgres.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/postgres.py @@ -1,37 +1,44 @@ """ - `PostgreSQL`_ database specific implementations of changeset classes. +`PostgreSQL`_ database specific implementations of changeset classes. - .. _`PostgreSQL`: http://www.postgresql.org/ +.. _`PostgreSQL`: http://www.postgresql.org/ """ + from rhodecode.lib.dbmigrate.migrate.changeset import ansisql from sqlalchemy.databases import postgresql as sa_base + PGSchemaGenerator = sa_base.PGDDLCompiler class PGColumnGenerator(PGSchemaGenerator, ansisql.ANSIColumnGenerator): """PostgreSQL column generator implementation.""" + pass class PGColumnDropper(ansisql.ANSIColumnDropper): """PostgreSQL column dropper implementation.""" + pass class PGSchemaChanger(ansisql.ANSISchemaChanger): """PostgreSQL schema changer implementation.""" + pass class PGConstraintGenerator(ansisql.ANSIConstraintGenerator): """PostgreSQL constraint generator implementation.""" + pass class PGConstraintDropper(ansisql.ANSIConstraintDropper): """PostgreSQL constaint dropper implementation.""" + pass diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/databases/sqlite.py b/rhodecode/lib/dbmigrate/migrate/changeset/databases/sqlite.py index a7150f5a..b4bafaa7 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/databases/sqlite.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/sqlite.py @@ -1,8 +1,9 @@ """ - `SQLite`_ database specific implementations of changeset classes. +`SQLite`_ database specific implementations of changeset classes. - .. _`SQLite`: http://www.sqlite.org/ +.. _`SQLite`: http://www.sqlite.org/ """ + try: # Python 3 from collections.abc import MutableMapping as DictMixin except ImportError: # Python 2 @@ -22,14 +23,13 @@ SQLiteSchemaGenerator = sa_base.SQLiteDDLCompiler class SQLiteCommon(object): - def _not_supported(self, op): - raise exceptions.NotSupportedError("SQLite does not support " - "%s; see http://www.sqlite.org/lang_altertable.html" % op) + raise exceptions.NotSupportedError( + "SQLite does not support %s; see http://www.sqlite.org/lang_altertable.html" % op + ) class SQLiteHelper(SQLiteCommon): - def _filter_columns(self, cols, table): """Splits the string of columns and returns those only in the table. @@ -58,7 +58,7 @@ class SQLiteHelper(SQLiteCommon): WHERE type='table' AND name=:table_name""", - table_name=table.name + table_name=table.name, ).fetchone()[0] UNIQUE_PATTERN = "CONSTRAINT (\w+) UNIQUE \(([^\)]+)\)" @@ -78,8 +78,7 @@ class SQLiteHelper(SQLiteCommon): return constraints - def recreate_table(self, table, column=None, delta=None, - omit_constraints=None): + def recreate_table(self, table, column=None, delta=None, omit_constraints=None): table_name = self.preparer.format_table(table) # we remove all indexes so as not to have @@ -91,29 +90,28 @@ class SQLiteHelper(SQLiteCommon): for constraint in self._get_constraints(table): table.append_constraint(constraint) # omit given constraints when creating a new table if required - table.constraints = set([ - cons for cons in table.constraints - if omit_constraints is None or cons.name not in omit_constraints - ]) + table.constraints = set( + [cons for cons in table.constraints if omit_constraints is None or cons.name not in omit_constraints] + ) # Use "PRAGMA legacy_alter_table = ON" with sqlite >= 3.26 when # using "ALTER TABLE RENAME TO migration_tmp" to maintain legacy # behavior. See: https://www.sqlite.org/src/info/ae9638e9c0ad0c36 if self.connection.engine.dialect.server_version_info >= (3, 26): - self.append('PRAGMA legacy_alter_table = ON') + self.append("PRAGMA legacy_alter_table = ON") self.execute() - self.append('ALTER TABLE %s RENAME TO migration_tmp' % table_name) + self.append("ALTER TABLE %s RENAME TO migration_tmp" % table_name) self.execute() if self.connection.engine.dialect.server_version_info >= (3, 26): - self.append('PRAGMA legacy_alter_table = OFF') + self.append("PRAGMA legacy_alter_table = OFF") self.execute() insertion_string = self._modify_table(table, column, delta) table.create(bind=self.connection) - self.append(insertion_string % {'table_name': table_name}) + self.append(insertion_string % {"table_name": table_name}) self.execute() - self.append('DROP TABLE migration_tmp') + self.append("DROP TABLE migration_tmp") self.execute() def visit_column(self, delta): @@ -123,62 +121,59 @@ class SQLiteHelper(SQLiteCommon): else: column = delta table = self._to_table(column.table) - self.recreate_table(table,column,delta) + self.recreate_table(table, column, delta) -class SQLiteColumnGenerator(SQLiteSchemaGenerator, - ansisql.ANSIColumnGenerator, - # at the end so we get the normal - # visit_column by default - SQLiteHelper, - SQLiteCommon - ): + +class SQLiteColumnGenerator( + SQLiteSchemaGenerator, + ansisql.ANSIColumnGenerator, + # at the end so we get the normal + # visit_column by default + SQLiteHelper, + SQLiteCommon, +): """SQLite ColumnGenerator""" def _modify_table(self, table, column, delta): - columns = ' ,'.join(map( - self.preparer.format_column, - [c for c in table.columns if c.name!=column.name])) - return ('INSERT INTO %%(table_name)s (%(cols)s) ' - 'SELECT %(cols)s from migration_tmp')%{'cols':columns} + columns = " ,".join(map(self.preparer.format_column, [c for c in table.columns if c.name != column.name])) + return ("INSERT INTO %%(table_name)s (%(cols)s) SELECT %(cols)s from migration_tmp") % {"cols": columns} - def visit_column(self,column): + def visit_column(self, column): if column.foreign_keys: - SQLiteHelper.visit_column(self,column) + SQLiteHelper.visit_column(self, column) else: - super(SQLiteColumnGenerator,self).visit_column(column) + super(SQLiteColumnGenerator, self).visit_column(column) + class SQLiteColumnDropper(SQLiteHelper, ansisql.ANSIColumnDropper): """SQLite ColumnDropper""" def _modify_table(self, table, column, delta): + columns = " ,".join(map(self.preparer.format_column, table.columns)) + return "INSERT INTO %(table_name)s SELECT " + columns + " from migration_tmp" - columns = ' ,'.join(map(self.preparer.format_column, table.columns)) - return 'INSERT INTO %(table_name)s SELECT ' + columns + \ - ' from migration_tmp' - - def visit_column(self,column): + def visit_column(self, column): # For SQLite, we *have* to remove the column here so the table # is re-created properly. - column.remove_from_table(column.table,unset_table=False) - super(SQLiteColumnDropper,self).visit_column(column) + column.remove_from_table(column.table, unset_table=False) + super(SQLiteColumnDropper, self).visit_column(column) class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger): """SQLite SchemaChanger""" def _modify_table(self, table, column, delta): - return 'INSERT INTO %(table_name)s SELECT * from migration_tmp' + return "INSERT INTO %(table_name)s SELECT * from migration_tmp" def visit_index(self, index): """Does not support ALTER INDEX""" - self._not_supported('ALTER INDEX') + self._not_supported("ALTER INDEX") class SQLiteConstraintGenerator(ansisql.ANSIConstraintGenerator, SQLiteHelper, SQLiteCommon): - def visit_migrate_primary_key_constraint(self, constraint): tmpl = "CREATE UNIQUE INDEX %s ON %s ( %s )" - cols = ', '.join(map(self.preparer.format_column, constraint.columns)) + cols = ", ".join(map(self.preparer.format_column, constraint.columns)) tname = self.preparer.format_table(constraint.table) name = self.get_constraint_name(constraint) msg = tmpl % (name, tname, cols) @@ -186,7 +181,7 @@ class SQLiteConstraintGenerator(ansisql.ANSIConstraintGenerator, SQLiteHelper, S self.execute() def _modify_table(self, table, column, delta): - return 'INSERT INTO %(table_name)s SELECT * from migration_tmp' + return "INSERT INTO %(table_name)s SELECT * from migration_tmp" def visit_migrate_foreign_key_constraint(self, *p, **k): self.recreate_table(p[0].table) @@ -195,12 +190,9 @@ class SQLiteConstraintGenerator(ansisql.ANSIConstraintGenerator, SQLiteHelper, S self.recreate_table(p[0].table) -class SQLiteConstraintDropper(ansisql.ANSIColumnDropper, - SQLiteHelper, - ansisql.ANSIConstraintCommon): - +class SQLiteConstraintDropper(ansisql.ANSIColumnDropper, SQLiteHelper, ansisql.ANSIConstraintCommon): def _modify_table(self, table, column, delta): - return 'INSERT INTO %(table_name)s SELECT * from migration_tmp' + return "INSERT INTO %(table_name)s SELECT * from migration_tmp" def visit_migrate_primary_key_constraint(self, constraint): tmpl = "DROP INDEX %s " @@ -210,11 +202,11 @@ class SQLiteConstraintDropper(ansisql.ANSIColumnDropper, self.execute() def visit_migrate_foreign_key_constraint(self, *p, **k): - #self._not_supported('ALTER TABLE DROP CONSTRAINT') + # self._not_supported('ALTER TABLE DROP CONSTRAINT') self.recreate_table(p[0].table, omit_constraints=[p[0].name]) def visit_migrate_check_constraint(self, *p, **k): - self._not_supported('ALTER TABLE DROP CONSTRAINT') + self._not_supported("ALTER TABLE DROP CONSTRAINT") def visit_migrate_unique_constraint(self, *p, **k): self.recreate_table(p[0].table, omit_constraints=[p[0].name]) @@ -222,6 +214,7 @@ class SQLiteConstraintDropper(ansisql.ANSIColumnDropper, # TODO: technically primary key is a NOT NULL + UNIQUE constraint, should add NOT NULL to index + class SQLiteDialect(ansisql.ANSIDialect): columngenerator = SQLiteColumnGenerator columndropper = SQLiteColumnDropper diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/databases/visitor.py b/rhodecode/lib/dbmigrate/migrate/changeset/databases/visitor.py index b515e0ae..cc911874 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/databases/visitor.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/databases/visitor.py @@ -1,14 +1,11 @@ """ - Module for visitor class mapping. +Module for visitor class mapping. """ + import sqlalchemy as sa from rhodecode.lib.dbmigrate.migrate.changeset import ansisql -from rhodecode.lib.dbmigrate.migrate.changeset.databases import (sqlite, - postgres, - mysql, - oracle, - firebird) +from rhodecode.lib.dbmigrate.migrate.changeset.databases import sqlite, postgres, mysql, oracle, firebird # Map SA dialects to the corresponding Migrate extensions @@ -28,6 +25,7 @@ DIALECTS = { # other dialects. try: from rhodecode.lib.dbmigrate.migrate.changeset.databases import ibmdb2 + DIALECTS["ibm_db_sa"] = ibmdb2.IBMDBDialect except ImportError: pass @@ -58,7 +56,7 @@ def get_dialect_visitor(sa_dialect, name): """ # map sa dialect to migrate dialect and return visitor - sa_dialect_name = getattr(sa_dialect, 'name', 'default') + sa_dialect_name = getattr(sa_dialect, "name", "default") migrate_dialect_cls = DIALECTS[sa_dialect_name] visitor = getattr(migrate_dialect_cls, name) @@ -67,8 +65,8 @@ def get_dialect_visitor(sa_dialect, name): return visitor -def run_single_visitor(engine, visitorcallable, element, - connection=None, **kwargs): + +def run_single_visitor(engine, visitorcallable, element, connection=None, **kwargs): """Taken from :meth:`sqlalchemy.engine.base.Engine._run_single_visitor` with support for migrate visitors. """ @@ -78,10 +76,10 @@ def run_single_visitor(engine, visitorcallable, element, conn = connection visitor = visitorcallable(engine.dialect, conn) try: - if hasattr(element, '__migrate_visit_name__'): - fn = getattr(visitor, 'visit_' + element.__migrate_visit_name__) + if hasattr(element, "__migrate_visit_name__"): + fn = getattr(visitor, "visit_" + element.__migrate_visit_name__) else: - fn = getattr(visitor, 'visit_' + element.__visit_name__) + fn = getattr(visitor, "visit_" + element.__visit_name__) fn(element, **kwargs) finally: if connection is None: diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/schema.py b/rhodecode/lib/dbmigrate/migrate/changeset/schema.py index c532c11a..c7f3f28e 100644 --- a/rhodecode/lib/dbmigrate/migrate/changeset/schema.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/schema.py @@ -1,7 +1,9 @@ """ - Schema module providing common schema operations. +Schema module providing common schema operations. """ + import abc + try: # Python 3 from collections.abc import MutableMapping as DictMixin except ImportError: # Python 2 @@ -16,21 +18,20 @@ from sqlalchemy.schema import UniqueConstraint from rhodecode.lib.dbmigrate.migrate.exceptions import * from rhodecode.lib.dbmigrate.migrate.changeset import SQLA_07, SQLA_08 from rhodecode.lib.dbmigrate.migrate.changeset import util -from rhodecode.lib.dbmigrate.migrate.changeset.databases.visitor import ( - get_engine_visitor, run_single_visitor) +from rhodecode.lib.dbmigrate.migrate.changeset.databases.visitor import get_engine_visitor, run_single_visitor __all__ = [ - 'create_column', - 'drop_column', - 'alter_column', - 'rename_table', - 'rename_index', - 'ChangesetTable', - 'ChangesetColumn', - 'ChangesetIndex', - 'ChangesetDefaultClause', - 'ColumnDelta', + "create_column", + "drop_column", + "alter_column", + "rename_table", + "rename_index", + "ChangesetTable", + "ChangesetColumn", + "ChangesetIndex", + "ChangesetDefaultClause", + "ColumnDelta", ] @@ -116,28 +117,27 @@ def alter_column(*p, **k): """ - if 'table' not in k and isinstance(p[0], sqlalchemy.Column): - k['table'] = p[0].table - if 'engine' not in k: - k['engine'] = k['table'].bind + if "table" not in k and isinstance(p[0], sqlalchemy.Column): + k["table"] = p[0].table + if "engine" not in k: + k["engine"] = k["table"].bind # deprecation if len(p) >= 2 and isinstance(p[1], sqlalchemy.Column): warnings.warn( - "Passing a Column object to alter_column is deprecated." - " Just pass in keyword parameters instead.", - MigrateDeprecationWarning - ) - engine = k['engine'] + "Passing a Column object to alter_column is deprecated. Just pass in keyword parameters instead.", + MigrateDeprecationWarning, + ) + engine = k["engine"] # enough tests seem to break when metadata is always altered # that this crutch has to be left in until they can be sorted # out - k['alter_metadata']=True + k["alter_metadata"] = True delta = ColumnDelta(*p, **k) - visitorcallable = get_engine_visitor(engine, 'schemachanger') + visitorcallable = get_engine_visitor(engine, "schemachanger") _run_visitor(engine, visitorcallable, delta) return delta @@ -167,17 +167,13 @@ def _to_index(index, table=None, engine=None): return ret -def _run_visitor( - connectable, visitorcallable, element, connection=None, **kwargs -): +def _run_visitor(connectable, visitorcallable, element, connection=None, **kwargs): if connection is not None: - visitorcallable( - connection.dialect, connection, **kwargs).traverse_single(element) + visitorcallable(connection.dialect, connection, **kwargs).traverse_single(element) else: conn = connectable.connect() try: - visitorcallable( - conn.dialect, conn, **kwargs).traverse_single(element) + visitorcallable(conn.dialect, conn, **kwargs).traverse_single(element) finally: conn.close() @@ -252,10 +248,9 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): """ # Column attributes that can be altered - diff_keys = ('name', 'type', 'primary_key', 'nullable', - 'server_onupdate', 'server_default', 'autoincrement') + diff_keys = ("name", "type", "primary_key", "nullable", "server_onupdate", "server_default", "autoincrement") diffs = dict() - __visit_name__ = 'column' + __visit_name__ = "column" def __init__(self, *p, **kw): # 'alter_metadata' is not a public api. It exists purely @@ -286,19 +281,16 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): self.apply_diffs(diffs) def __repr__(self): - return '' % ( - self.alter_metadata, - super(ColumnDelta, self).__repr__() - ) + return "" % (self.alter_metadata, super(ColumnDelta, self).__repr__()) def __getitem__(self, key): if key not in list(self.keys()): - raise KeyError("No such diff key, available: %s" % self.diffs ) + raise KeyError("No such diff key, available: %s" % self.diffs) return getattr(self.result_column, key) def __setitem__(self, key, value): if key not in list(self.keys()): - raise KeyError("No such diff key, available: %s" % self.diffs ) + raise KeyError("No such diff key, available: %s" % self.diffs) setattr(self.result_column, key, value) def __delitem__(self, key): @@ -315,7 +307,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): def compare_parameters(self, current_name, *p, **k): """Compares Column objects with reflection""" - self.table = k.pop('table') + self.table = k.pop("table") self.result_column = self._table.c.get(current_name) if len(p): k = self._extract_parameters(p, k, self.result_column) @@ -323,7 +315,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): def compare_1_column(self, col, *p, **k): """Compares one Column object""" - self.table = k.pop('table', None) + self.table = k.pop("table", None) if self.table is None: self.table = col.table self.result_column = col @@ -334,7 +326,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): def compare_2_columns(self, old_col, new_col, *p, **k): """Compares two Column objects""" self.process_column(new_col) - self.table = k.pop('table', None) + self.table = k.pop("table", None) # we cannot use bool() on table in SA06 if self.table is None: self.table = old_col.table @@ -344,14 +336,14 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): # set differences # leave out some stuff for later comp - for key in (set(self.diff_keys) - set(('type',))): + for key in set(self.diff_keys) - set(("type",)): val = getattr(new_col, key, None) if getattr(self.result_column, key, None) != val: k.setdefault(key, val) # inspect types if not self.are_column_types_eq(self.result_column.type, new_col.type): - k.setdefault('type', new_col.type) + k.setdefault("type", new_col.type) if len(p): k = self._extract_parameters(p, k, self.result_column) @@ -367,13 +359,12 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): self.process_column(self.result_column) # create an instance of class type if not yet - if 'type' in diffs: + if "type" in diffs: if callable(self.result_column.type): self.result_column.type = self.result_column.type() - if self.result_column.autoincrement and \ - not issubclass( - self.result_column.type._type_affinity, - sqlalchemy.Integer): + if self.result_column.autoincrement and not issubclass( + self.result_column.type._type_affinity, sqlalchemy.Integer + ): self.result_column.autoincrement = False # add column to the table @@ -386,8 +377,7 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): # String length is a special case if ret and isinstance(new_type, sqlalchemy.types.String): - ret = (getattr(old_type, 'length', None) == \ - getattr(new_type, 'length', None)) + ret = getattr(old_type, "length", None) == getattr(new_type, "length", None) return ret def _extract_parameters(self, p, k, column): @@ -395,9 +385,9 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): p = list(p) while len(p): if isinstance(p[0], str): - k.setdefault('name', p.pop(0)) + k.setdefault("name", p.pop(0)) elif isinstance(p[0], sqlalchemy.types.TypeEngine): - k.setdefault('type', p.pop(0)) + k.setdefault("type", p.pop(0)) elif callable(p[0]): p[0] = p[0]() else: @@ -423,27 +413,24 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): if isinstance(column.server_onupdate, FetchedValue): toinit.append(column.server_default) else: - toinit.append(sqlalchemy.DefaultClause(column.server_onupdate, - for_update=True)) + toinit.append(sqlalchemy.DefaultClause(column.server_onupdate, for_update=True)) if toinit: column._init_items(*toinit) def _get_table(self): - return getattr(self, '_table', None) + return getattr(self, "_table", None) def _set_table(self, table): if isinstance(table, str): if self.alter_metadata: if not self.meta: - raise ValueError("metadata must be specified for table" - " reflection when using alter_metadata") + raise ValueError("metadata must be specified for table reflection when using alter_metadata") meta = self.meta if self.engine: meta.bind = self.engine else: if not self.engine and not self.meta: - raise ValueError("engine or metadata must be specified" - " to reflect tables") + raise ValueError("engine or metadata must be specified to reflect tables") if not self.engine: self.engine = self.meta.bind meta = sqlalchemy.MetaData(bind=self.engine) @@ -452,13 +439,14 @@ class ColumnDelta(DictMixin, sqlalchemy.schema.SchemaItem, metaclass=MyMeta): self._table = table if not self.alter_metadata: self._table.meta = sqlalchemy.MetaData(bind=self._table.bind) + def _get_result_column(self): - return getattr(self, '_result_column', None) + return getattr(self, "_result_column", None) def _set_result_column(self, column): """Set Column to Table based on alter_metadata evaluation.""" self.process_column(column) - if not hasattr(self, 'current_name'): + if not hasattr(self, "current_name"): self.current_name = column.name if self.alter_metadata: self._result_column = column @@ -517,7 +505,7 @@ class ChangesetTable(object): """ engine = self.bind self.new_name = name - visitorcallable = get_engine_visitor(engine, 'schemachanger') + visitorcallable = get_engine_visitor(engine, "schemachanger") run_single_visitor(engine, visitorcallable, self, connection, **kwargs) # Fix metadata registration @@ -547,14 +535,22 @@ class ChangesetColumn(object): """Makes a call to :func:`alter_column` for the column this method is called on. """ - if 'table' not in k: - k['table'] = self.table - if 'engine' not in k: - k['engine'] = k['table'].bind + if "table" not in k: + k["table"] = self.table + if "engine" not in k: + k["engine"] = k["table"].bind return alter_column(self, *p, **k) - def create(self, table=None, index_name=None, unique_name=None, - primary_key_name=None, populate_default=True, connection=None, **kwargs): + def create( + self, + table=None, + index_name=None, + unique_name=None, + primary_key_name=None, + populate_default=True, + connection=None, + **kwargs, + ): """Create this column in the database. Assumes the given table exists. ``ALTER TABLE ADD COLUMN``, @@ -582,12 +578,12 @@ populated with defaults self.index_name = index_name self.unique_name = unique_name self.primary_key_name = primary_key_name - for cons in ('index_name', 'unique_name', 'primary_key_name'): + for cons in ("index_name", "unique_name", "primary_key_name"): self._check_sanity_constraints(cons) self.add_to_table(table) engine = self.table.bind - visitorcallable = get_engine_visitor(engine, 'columngenerator') + visitorcallable = get_engine_visitor(engine, "columngenerator") _run_visitor(engine, visitorcallable, self, connection, **kwargs) # TODO: reuse existing connection @@ -608,20 +604,20 @@ populated with defaults if table is not None: self.table = table engine = self.table.bind - visitorcallable = get_engine_visitor(engine, 'columndropper') + visitorcallable = get_engine_visitor(engine, "columndropper") _run_visitor(engine, visitorcallable, self, connection, **kwargs) self.remove_from_table(self.table, unset_table=False) self.table = None return self def add_to_table(self, table): - if table is not None and self.table is None: + if table is not None and self.table is None: if SQLA_07: table.append_column(self) else: self._set_parent(table) - def _col_name_in_constraint(self,cons,name): + def _col_name_in_constraint(self, cons, name): return False def remove_from_table(self, table, unset_table=True): @@ -633,7 +629,7 @@ populated with defaults for index in table.indexes: columns = [] for col in index.columns: - if col.name!=self.name: + if col.name != self.name: columns.append(col) if columns: index.columns = columns @@ -646,12 +642,11 @@ populated with defaults to_drop = set() for cons in table.constraints: # TODO: deal with other types of constraint - if isinstance(cons,(ForeignKeyConstraint, - UniqueConstraint)): + if isinstance(cons, (ForeignKeyConstraint, UniqueConstraint)): for col_name in cons.columns: if not isinstance(col_name, str): col_name = col_name.name - if self.name==col_name: + if self.name == col_name: to_drop.add(cons) table.constraints = table.constraints - to_drop @@ -665,7 +660,10 @@ populated with defaults def copy_fixed(self, **kw): """Create a copy of this ``Column``, with all attributes.""" q = util.safe_quote(self) - return sqlalchemy.Column(self.name, self.type, self.default, + return sqlalchemy.Column( + self.name, + self.type, + self.default, key=self.key, primary_key=self.primary_key, nullable=self.nullable, @@ -676,23 +674,24 @@ populated with defaults autoincrement=self.autoincrement, server_default=self.server_default, server_onupdate=self.server_onupdate, - *[c.copy(**kw) for c in self.constraints]) + *[c.copy(**kw) for c in self.constraints], + ) def _check_sanity_constraints(self, name): """Check if constraints names are correct""" obj = getattr(self, name) - if (getattr(self, name[:-5]) and not obj): - raise InvalidConstraintError("Column.create() accepts index_name," - " primary_key_name and unique_name to generate constraints") - if not isinstance(obj, str) and obj is not None: + if getattr(self, name[:-5]) and not obj: raise InvalidConstraintError( - "%s argument for column must be constraint name" % name) + "Column.create() accepts index_name, primary_key_name and unique_name to generate constraints" + ) + if not isinstance(obj, str) and obj is not None: + raise InvalidConstraintError("%s argument for column must be constraint name" % name) class ChangesetIndex(object): """Changeset extensions to SQLAlchemy Indexes.""" - __visit_name__ = 'index' + __visit_name__ = "index" def rename(self, name, connection=None, **kwargs): """Change the name of an index. @@ -704,7 +703,7 @@ class ChangesetIndex(object): """ engine = self.table.bind self.new_name = name - visitorcallable = get_engine_visitor(engine, 'schemachanger') + visitorcallable = get_engine_visitor(engine, "schemachanger") engine._run_visitor(visitorcallable, self, connection, **kwargs) self.name = name diff --git a/rhodecode/lib/dbmigrate/migrate/changeset/util.py b/rhodecode/lib/dbmigrate/migrate/changeset/util.py index 092fc4a7..e9e32885 100755 --- a/rhodecode/lib/dbmigrate/migrate/changeset/util.py +++ b/rhodecode/lib/dbmigrate/migrate/changeset/util.py @@ -1,21 +1,20 @@ """ Safe quoting method """ + from rhodecode.lib.dbmigrate.migrate.changeset import SQLA_10 def fk_column_names(constraint): if SQLA_10: - return [ - constraint.columns[key].name for key in constraint.column_keys] + return [constraint.columns[key].name for key in constraint.column_keys] else: - return [ - element.parent.name for element in constraint.elements] + return [element.parent.name for element in constraint.elements] def safe_quote(obj): # this is the SQLA 0.9 approach - if hasattr(obj, 'name') and hasattr(obj.name, 'quote'): + if hasattr(obj, "name") and hasattr(obj.name, "quote"): return obj.name.quote else: return obj.quote diff --git a/rhodecode/lib/dbmigrate/migrate/exceptions.py b/rhodecode/lib/dbmigrate/migrate/exceptions.py index 31c8cd96..4708df6c 100644 --- a/rhodecode/lib/dbmigrate/migrate/exceptions.py +++ b/rhodecode/lib/dbmigrate/migrate/exceptions.py @@ -1,5 +1,5 @@ """ - Provide exception classes for :mod:`migrate` +Provide exception classes for :mod:`migrate` """ @@ -78,8 +78,10 @@ class InvalidScriptError(ScriptError): class InvalidVersionError(Error): """Invalid version error.""" + # migrate.changeset + class NotSupportedError(Error): """Not supported error""" @@ -87,5 +89,6 @@ class NotSupportedError(Error): class InvalidConstraintError(Error): """Invalid constraint error""" + class MigrateDeprecationWarning(DeprecationWarning): """Warning for deprecated features in Migrate""" diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/__init__.py b/rhodecode/lib/dbmigrate/migrate/versioning/__init__.py index 8b5a7363..382f72a7 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/__init__.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/__init__.py @@ -1,5 +1,5 @@ """ - This package provides functionality to create and manage - repositories of database schema changesets and to apply these - changesets to databases. +This package provides functionality to create and manage +repositories of database schema changesets and to apply these +changesets to databases. """ diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/api.py b/rhodecode/lib/dbmigrate/migrate/versioning/api.py index 683ddd56..234be5c7 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/api.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/api.py @@ -1,19 +1,19 @@ """ - This module provides an external API to the versioning system. +This module provides an external API to the versioning system. - .. versionchanged:: 0.6.0 - :func:`migrate.versioning.api.test` and schema diff functions - changed order of positional arguments so all accept `url` and `repository` - as first arguments. +.. versionchanged:: 0.6.0 + :func:`migrate.versioning.api.test` and schema diff functions + changed order of positional arguments so all accept `url` and `repository` + as first arguments. - .. versionchanged:: 0.5.4 - ``--preview_sql`` displays source file when using SQL scripts. - If Python script is used, it runs the action with mocked engine and - returns captured SQL statements. +.. versionchanged:: 0.5.4 + ``--preview_sql`` displays source file when using SQL scripts. + If Python script is used, it runs the action with mocked engine and + returns captured SQL statements. - .. versionchanged:: 0.5.4 - Deprecated ``--echo`` parameter in favour of new - :func:`migrate.versioning.util.construct_engine` behavior. +.. versionchanged:: 0.5.4 + Deprecated ``--echo`` parameter in favour of new + :func:`migrate.versioning.util.construct_engine` behavior. """ # Dear migrate developers, @@ -31,32 +31,33 @@ import logging from rhodecode.lib.dbmigrate.migrate import exceptions from rhodecode.lib.dbmigrate.migrate.versioning import ( - repository, schema, version, - script as script_ # command name conflict + repository, + schema, + version, + script as script_, # command name conflict ) -from rhodecode.lib.dbmigrate.migrate.versioning.util import ( - catch_known_errors, with_engine) +from rhodecode.lib.dbmigrate.migrate.versioning.util import catch_known_errors, with_engine log = logging.getLogger(__name__) command_desc = { - 'help': 'displays help on a given command', - 'create': 'create an empty repository at the specified path', - 'script': 'create an empty change Python script', - 'script_sql': 'create empty change SQL scripts for given database', - 'version': 'display the latest version available in a repository', - 'db_version': 'show the current version of the repository under version control', - 'source': 'display the Python code for a particular version in this repository', - 'version_control': 'mark a database as under this repository\'s version control', - 'upgrade': 'upgrade a database to a later version', - 'downgrade': 'downgrade a database to an earlier version', - 'drop_version_control': 'removes version control from a database', - 'manage': 'creates a Python script that runs Migrate with a set of default values', - 'test': 'performs the upgrade and downgrade command on the given database', - 'compare_model_to_db': 'compare MetaData against the current database state', - 'create_model': 'dump the current database as a Python model to stdout', - 'make_update_script_for_model': 'create a script changing the old MetaData to the new (current) MetaData', - 'update_db_from_model': 'modify the database to match the structure of the current MetaData', + "help": "displays help on a given command", + "create": "create an empty repository at the specified path", + "script": "create an empty change Python script", + "script_sql": "create empty change SQL scripts for given database", + "version": "display the latest version available in a repository", + "db_version": "show the current version of the repository under version control", + "source": "display the Python code for a particular version in this repository", + "version_control": "mark a database as under this repository's version control", + "upgrade": "upgrade a database to a later version", + "downgrade": "downgrade a database to an earlier version", + "drop_version_control": "removes version control from a database", + "manage": "creates a Python script that runs Migrate with a set of default values", + "test": "performs the upgrade and downgrade command on the given database", + "compare_model_to_db": "compare MetaData against the current database state", + "create_model": "dump the current database as a Python model to stdout", + "make_update_script_for_model": "create a script changing the old MetaData to the new (current) MetaData", + "update_db_from_model": "modify the database to match the structure of the current MetaData", } __all__ = list(command_desc.keys()) @@ -78,13 +79,13 @@ def help(cmd=None, **opts): try: func = globals()[cmd] except: - raise exceptions.UsageError( - "'%s' isn't a valid command. Try 'help COMMAND'" % cmd) + raise exceptions.UsageError("'%s' isn't a valid command. Try 'help COMMAND'" % cmd) ret = func.__doc__ if sys.argv[0]: - ret = ret.replace('%prog', sys.argv[0]) + ret = ret.replace("%prog", sys.argv[0]) return ret + @catch_known_errors def create(repository, name, **opts): """%prog create REPOSITORY_PATH NAME [--table=TABLE] @@ -147,7 +148,7 @@ def db_version(url, repository, **opts): The url should be any valid SQLAlchemy connection string. """ - engine = opts.pop('engine') + engine = opts.pop("engine") schema = ControlledSchema(engine, repository) return schema.version @@ -164,7 +165,7 @@ def source(version, dest=None, repository=None, **opts): repo = Repository(repository) ret = repo.version(version).script().source() if dest is not None: - with open(dest, 'w') as f: + with open(dest, "w") as f: f.write(ret) ret = None return ret @@ -183,8 +184,7 @@ def upgrade(url, repository, version=None, **opts): You may preview the Python or SQL code to be executed, rather than actually executing it, using the appropriate 'preview' option. """ - err = "Cannot upgrade a database of version %s to version %s. "\ - "Try 'downgrade' instead." + err = "Cannot upgrade a database of version %s to version %s. Try 'downgrade' instead." return _migrate(url, repository, version, upgrade=True, err=err, **opts) @@ -199,10 +199,10 @@ def downgrade(url, repository, version, **opts): You may preview the Python or SQL code to be executed, rather than actually executing it, using the appropriate 'preview' option. """ - err = "Cannot downgrade a database of version %s to version %s. "\ - "Try 'upgrade' instead." + err = "Cannot downgrade a database of version %s to version %s. Try 'upgrade' instead." return _migrate(url, repository, version, upgrade=False, err=err, **opts) + @with_engine def test(url, repository, **opts): """%prog test URL REPOSITORY_PATH [VERSION] @@ -212,17 +212,17 @@ def test(url, repository, **opts): bad state. You should therefore better run the test on a copy of your database. """ - engine = opts.pop('engine') + engine = opts.pop("engine") repos = Repository(repository) # Upgrade log.info("Upgrading...") - script = repos.version(None).script(engine.name, 'upgrade') + script = repos.version(None).script(engine.name, "upgrade") script.run(engine, 1) log.info("done") log.info("Downgrading...") - script = repos.version(None).script(engine.name, 'downgrade') + script = repos.version(None).script(engine.name, "downgrade") script.run(engine, -1) log.info("done") log.info("Success") @@ -248,7 +248,7 @@ def version_control(url, repository, version=None, **opts): identical to what it would be if the database were created from scratch. """ - engine = opts.pop('engine') + engine = opts.pop("engine") ControlledSchema.create(engine, repository, version) @@ -258,7 +258,7 @@ def drop_version_control(url, repository, **opts): Removes version control from a database. """ - engine = opts.pop('engine') + engine = opts.pop("engine") schema = ControlledSchema(engine, repository) schema.drop() @@ -291,7 +291,7 @@ def compare_model_to_db(url, repository, model, **opts): NOTE: This is EXPERIMENTAL. """ # TODO: get rid of EXPERIMENTAL label - engine = opts.pop('engine') + engine = opts.pop("engine") return ControlledSchema.compare_model_to_db(engine, model, repository) @@ -303,8 +303,8 @@ def create_model(url, repository, **opts): NOTE: This is EXPERIMENTAL. """ # TODO: get rid of EXPERIMENTAL label - engine = opts.pop('engine') - declarative = opts.get('declarative', False) + engine = opts.pop("engine") + declarative = opts.get("declarative", False) return ControlledSchema.create_model(engine, repository, declarative) @@ -318,9 +318,8 @@ def make_update_script_for_model(url, repository, oldmodel, model, **opts): NOTE: This is EXPERIMENTAL. """ # TODO: get rid of EXPERIMENTAL label - engine = opts.pop('engine') - return PythonScript.make_update_script_for_model( - engine, oldmodel, model, repository, **opts) + engine = opts.pop("engine") + return PythonScript.make_update_script_for_model(engine, oldmodel, model, repository, **opts) @with_engine @@ -333,13 +332,14 @@ def update_db_from_model(url, repository, model, **opts): NOTE: This is EXPERIMENTAL. """ # TODO: get rid of EXPERIMENTAL label - engine = opts.pop('engine') + engine = opts.pop("engine") schema = ControlledSchema(engine, repository) schema.update_db_from_model(model) + @with_engine def _migrate(url, repository, version, upgrade, err, **opts): - engine = opts.pop('engine') + engine = opts.pop("engine") url = str(engine.url) schema = ControlledSchema(engine, repository) version = _migrate_version(schema, version, upgrade, err) @@ -347,18 +347,17 @@ def _migrate(url, repository, version, upgrade, err, **opts): changeset = schema.changeset(version) for ver, change in changeset: nextver = ver + changeset.step - log.info('%s -> %s... ', ver, nextver) + log.info("%s -> %s... ", ver, nextver) - if opts.get('preview_sql'): + if opts.get("preview_sql"): if isinstance(change, PythonScript): log.info(change.preview_sql(url, changeset.step, **opts)) elif isinstance(change, SqlScript): log.info(change.source()) - elif opts.get('preview_py'): + elif opts.get("preview_py"): if not isinstance(change, PythonScript): - raise exceptions.UsageError("Python source can be only displayed" - " for python migration files") + raise exceptions.UsageError("Python source can be only displayed for python migration files") source_ver = max(ver, nextver) module = schema.repository.version(source_ver).script().module funcname = upgrade and "upgrade" or "downgrade" @@ -366,7 +365,7 @@ def _migrate(url, repository, version, upgrade, err, **opts): log.info(inspect.getsource(func)) else: schema.runchange(ver, change, changeset.step) - log.info('done') + log.info("done") def _migrate_version(schema, version, upgrade, err): diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/cfgparse.py b/rhodecode/lib/dbmigrate/migrate/versioning/cfgparse.py index 771e2b05..5a94adc5 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/cfgparse.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/cfgparse.py @@ -1,5 +1,5 @@ """ - Configuration parser module. +Configuration parser module. """ from configparser import ConfigParser diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/config.py b/rhodecode/lib/dbmigrate/migrate/versioning/config.py index 2c222690..6ce81d3e 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/config.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/config.py @@ -4,11 +4,11 @@ from sqlalchemy.util import OrderedDict -__all__ = ['databases', 'operations'] +__all__ = ["databases", "operations"] -databases = ('sqlite', 'postgres', 'mysql', 'oracle', 'mssql', 'firebird') +databases = ("sqlite", "postgres", "mysql", "oracle", "mssql", "firebird") # Map operation names to function names operations = OrderedDict() -operations['upgrade'] = 'upgrade' -operations['downgrade'] = 'downgrade' +operations["upgrade"] = "upgrade" +operations["downgrade"] = "downgrade" diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/genmodel.py b/rhodecode/lib/dbmigrate/migrate/versioning/genmodel.py index 22f22706..ab348ec7 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/genmodel.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/genmodel.py @@ -48,14 +48,14 @@ class ModelGenerator(object): def column_repr(self, col): kwarg = [] if col.key != col.name: - kwarg.append('key') + kwarg.append("key") if col.primary_key: col.primary_key = True # otherwise it dumps it as 1 - kwarg.append('primary_key') + kwarg.append("primary_key") if not col.nullable: - kwarg.append('nullable') + kwarg.append("nullable") if col.onupdate: - kwarg.append('onupdate') + kwarg.append("onupdate") if col.default: if col.primary_key: # I found that PostgreSQL automatically creates a @@ -63,30 +63,29 @@ class ModelGenerator(object): # that. pass else: - kwarg.append('default') - args = ['%s=%r' % (k, getattr(col, k)) for k in kwarg] + kwarg.append("default") + args = ["%s=%r" % (k, getattr(col, k)) for k in kwarg] # crs: not sure if this is good idea, but it gets rid of extra # u'' - name = col.name#.encode('utf8') + name = col.name # .encode('utf8') type_ = col.type for cls in col.type.__class__.__mro__: - if cls.__module__ == 'sqlalchemy.types' and \ - not cls.__name__.isupper(): + if cls.__module__ == "sqlalchemy.types" and not cls.__name__.isupper(): if cls is not type_.__class__: type_ = cls() break type_repr = repr(type_) - if type_repr.endswith('()'): + if type_repr.endswith("()"): type_repr = type_repr[:-2] constraints = [repr(cn) for cn in col.constraints] data = { - 'name': name, - 'commonStuff': ', '.join([type_repr] + constraints + args), + "name": name, + "commonStuff": ", ".join([type_repr] + constraints + args), } if self.declarative: @@ -94,31 +93,29 @@ class ModelGenerator(object): else: return """Column(%(name)r, %(commonStuff)s)""" % data - def _getTableDefn(self, table, metaName='meta'): + def _getTableDefn(self, table, metaName="meta"): out = [] tableName = table.name if self.declarative: - out.append("class %(table)s(Base):" % {'table': tableName}) - out.append(" __tablename__ = '%(table)s'\n" % - {'table': tableName}) + out.append("class %(table)s(Base):" % {"table": tableName}) + out.append(" __tablename__ = '%(table)s'\n" % {"table": tableName}) for col in table.columns: out.append(" %s" % self.column_repr(col)) - out.append('\n') + out.append("\n") else: - out.append("%(table)s = Table('%(table)s', %(meta)s," % - {'table': tableName, 'meta': metaName}) + out.append("%(table)s = Table('%(table)s', %(meta)s," % {"table": tableName, "meta": metaName}) for col in table.columns: out.append(" %s," % self.column_repr(col)) out.append(")\n") return out - def _get_tables(self,missingA=False,missingB=False,modified=False): + def _get_tables(self, missingA=False, missingB=False, modified=False): to_process = [] - for bool_,names,metadata in ( - (missingA,self.diff.tables_missing_from_A,self.diff.metadataB), - (missingB,self.diff.tables_missing_from_B,self.diff.metadataA), - (modified,self.diff.tables_different,self.diff.metadataA), - ): + for bool_, names, metadata in ( + (missingA, self.diff.tables_missing_from_A, self.diff.metadataB), + (missingB, self.diff.tables_missing_from_B, self.diff.metadataA), + (modified, self.diff.tables_different, self.diff.metadataA), + ): if bool_: for name in names: yield metadata.tables.get(name) @@ -131,10 +128,8 @@ class ModelGenerator(object): for table in tables: for col in table.columns: - if "dialects" in col.type.__module__ and \ - col.type.__class__ not in import_index: - out.append("from " + col.type.__module__ + - " import " + col.type.__class__.__name__) + if "dialects" in col.type.__module__ and col.type.__class__ not in import_index: + out.append("from " + col.type.__module__ + " import " + col.type.__class__.__name__) import_index.append(col.type.__class__) out.append("") @@ -159,82 +154,71 @@ class ModelGenerator(object): out.extend(self._genModelHeader(self._get_tables(missingA=True))) for table in self._get_tables(missingA=True): out.extend(self._getTableDefn(table)) - return '\n'.join(out) + return "\n".join(out) - def genB2AMigration(self, indent=' '): + def genB2AMigration(self, indent=" "): """Generate a migration from B to A. Was: toUpgradeDowngradePython Assume model (A) is most current and database (B) is out-of-date. """ - decls = ['from rhodecode.lib.dbmigrate.migrate.changeset import schema', - 'pre_meta = MetaData()', - 'post_meta = MetaData()', - ] - upgradeCommands = ['pre_meta.bind = migrate_engine', - 'post_meta.bind = migrate_engine'] + decls = [ + "from rhodecode.lib.dbmigrate.migrate.changeset import schema", + "pre_meta = MetaData()", + "post_meta = MetaData()", + ] + upgradeCommands = ["pre_meta.bind = migrate_engine", "post_meta.bind = migrate_engine"] downgradeCommands = list(upgradeCommands) for tn in self.diff.tables_missing_from_A: pre_table = self.diff.metadataB.tables[tn] - decls.extend(self._getTableDefn(pre_table, metaName='pre_meta')) - upgradeCommands.append( - "pre_meta.tables[%(table)r].drop()" % {'table': tn}) - downgradeCommands.append( - "pre_meta.tables[%(table)r].create()" % {'table': tn}) + decls.extend(self._getTableDefn(pre_table, metaName="pre_meta")) + upgradeCommands.append("pre_meta.tables[%(table)r].drop()" % {"table": tn}) + downgradeCommands.append("pre_meta.tables[%(table)r].create()" % {"table": tn}) for tn in self.diff.tables_missing_from_B: post_table = self.diff.metadataA.tables[tn] - decls.extend(self._getTableDefn(post_table, metaName='post_meta')) - upgradeCommands.append( - "post_meta.tables[%(table)r].create()" % {'table': tn}) - downgradeCommands.append( - "post_meta.tables[%(table)r].drop()" % {'table': tn}) + decls.extend(self._getTableDefn(post_table, metaName="post_meta")) + upgradeCommands.append("post_meta.tables[%(table)r].create()" % {"table": tn}) + downgradeCommands.append("post_meta.tables[%(table)r].drop()" % {"table": tn}) - for (tn, td) in list(self.diff.tables_different.items()): + for tn, td in list(self.diff.tables_different.items()): if td.columns_missing_from_A or td.columns_different: pre_table = self.diff.metadataB.tables[tn] - decls.extend(self._getTableDefn( - pre_table, metaName='pre_meta')) + decls.extend(self._getTableDefn(pre_table, metaName="pre_meta")) if td.columns_missing_from_B or td.columns_different: post_table = self.diff.metadataA.tables[tn] - decls.extend(self._getTableDefn( - post_table, metaName='post_meta')) + decls.extend(self._getTableDefn(post_table, metaName="post_meta")) for col in td.columns_missing_from_A: - upgradeCommands.append( - 'pre_meta.tables[%r].columns[%r].drop()' % (tn, col)) - downgradeCommands.append( - 'pre_meta.tables[%r].columns[%r].create()' % (tn, col)) + upgradeCommands.append("pre_meta.tables[%r].columns[%r].drop()" % (tn, col)) + downgradeCommands.append("pre_meta.tables[%r].columns[%r].create()" % (tn, col)) for col in td.columns_missing_from_B: - upgradeCommands.append( - 'post_meta.tables[%r].columns[%r].create()' % (tn, col)) - downgradeCommands.append( - 'post_meta.tables[%r].columns[%r].drop()' % (tn, col)) + upgradeCommands.append("post_meta.tables[%r].columns[%r].create()" % (tn, col)) + downgradeCommands.append("post_meta.tables[%r].columns[%r].drop()" % (tn, col)) for modelCol, databaseCol, modelDecl, databaseDecl in td.columns_different: upgradeCommands.append( - 'assert False, "Can\'t alter columns: %s:%s=>%s"' % ( - tn, modelCol.name, databaseCol.name)) + 'assert False, "Can\'t alter columns: %s:%s=>%s"' % (tn, modelCol.name, databaseCol.name) + ) downgradeCommands.append( - 'assert False, "Can\'t alter columns: %s:%s=>%s"' % ( - tn, modelCol.name, databaseCol.name)) + 'assert False, "Can\'t alter columns: %s:%s=>%s"' % (tn, modelCol.name, databaseCol.name) + ) return ( - '\n'.join(decls), - '\n'.join('%s%s' % (indent, line) for line in upgradeCommands), - '\n'.join('%s%s' % (indent, line) for line in downgradeCommands)) + "\n".join(decls), + "\n".join("%s%s" % (indent, line) for line in upgradeCommands), + "\n".join("%s%s" % (indent, line) for line in downgradeCommands), + ) - def _db_can_handle_this_change(self,td): + def _db_can_handle_this_change(self, td): """Check if the database can handle going from B to A.""" - if (td.columns_missing_from_B - and not td.columns_missing_from_A - and not td.columns_different): + if td.columns_missing_from_B and not td.columns_missing_from_A and not td.columns_different: # Even sqlite can handle column additions. return True else: - return not self.engine.url.drivername.startswith('sqlite') + return not self.engine.url.drivername.startswith("sqlite") def runB2A(self): """Goes from B to A. @@ -258,7 +242,6 @@ class ModelGenerator(object): td = self.diff.tables_different[tableName] if self._db_can_handle_this_change(td): - for col in td.columns_missing_from_B: modelTable.columns[col].create() for col in td.columns_missing_from_A: @@ -270,7 +253,7 @@ class ModelGenerator(object): # old table, create new table, copy data back. # # I wonder if this is guaranteed to be unique? - tempName = '_temp_%s' % modelTable.name + tempName = "_temp_%s" % modelTable.name def getCopyStatement(): preparer = self.engine.dialect.preparer @@ -278,24 +261,21 @@ class ModelGenerator(object): for modelCol in modelTable.columns: if modelCol.name in dbTable.columns: commonCols.append(modelCol.name) - commonColsStr = ', '.join(commonCols) - return 'INSERT INTO %s (%s) SELECT %s FROM %s' % \ - (tableName, commonColsStr, commonColsStr, tempName) + commonColsStr = ", ".join(commonCols) + return "INSERT INTO %s (%s) SELECT %s FROM %s" % (tableName, commonColsStr, commonColsStr, tempName) # Move the data in one transaction, so that we don't # leave the database in a nasty state. connection = self.engine.connect() trans = connection.begin() try: - connection.execute( - 'CREATE TEMPORARY TABLE %s as SELECT * from %s' % \ - (tempName, modelTable.name)) + connection.execute("CREATE TEMPORARY TABLE %s as SELECT * from %s" % (tempName, modelTable.name)) # make sure the drop takes place inside our # transaction with the bind parameter modelTable.drop(bind=connection) modelTable.create(bind=connection) connection.execute(getCopyStatement()) - connection.execute('DROP TABLE %s' % tempName) + connection.execute("DROP TABLE %s" % tempName) trans.commit() except: trans.rollback() diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/migrate_repository.py b/rhodecode/lib/dbmigrate/migrate/versioning/migrate_repository.py index 2188bc61..e80d1b38 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/migrate_repository.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/migrate_repository.py @@ -1,7 +1,7 @@ """ - Script to migrate repository from sqlalchemy <= 0.4.4 to the new - repository schema. This shouldn't use any other migrate modules, so - that it can work in any version. +Script to migrate repository from sqlalchemy <= 0.4.4 to the new +repository schema. This shouldn't use any other migrate modules, so +that it can work in any version. """ import os @@ -13,76 +13,78 @@ log = logging.getLogger(__name__) def usage(): """Gives usage information.""" - print(("""Usage: %(prog)s repository-to-migrate + print( + ( + """Usage: %(prog)s repository-to-migrate Upgrade your repository to the new flat format. NOTE: You should probably make a backup before running this. - """ % {'prog': sys.argv[0]})) + """ + % {"prog": sys.argv[0]} + ) + ) sys.exit(1) def delete_file(filepath): """Deletes a file and prints a message.""" - log.info('Deleting file: %s', filepath) + log.info("Deleting file: %s", filepath) os.remove(filepath) def move_file(src, tgt): """Moves a file and prints a message.""" - log.info('Moving file %s to %s', src, tgt) + log.info("Moving file %s to %s", src, tgt) if os.path.exists(tgt): - raise Exception( - 'Cannot move file %s because target %s already exists' % \ - (src, tgt)) + raise Exception("Cannot move file %s because target %s already exists" % (src, tgt)) os.rename(src, tgt) def delete_directory(dirpath): """Delete a directory and print a message.""" - log.info('Deleting directory: %s', dirpath) + log.info("Deleting directory: %s", dirpath) os.rmdir(dirpath) def migrate_repository(repos): """Does the actual migration to the new repository format.""" - log.info('Migrating repository at: %s to new format', repos) - versions = '%s/versions' % repos + log.info("Migrating repository at: %s to new format", repos) + versions = "%s/versions" % repos dirs = os.listdir(versions) # Only use int's in list. numdirs = [int(dirname) for dirname in dirs if dirname.isdigit()] numdirs.sort() # Sort list. for dirname in numdirs: - origdir = '%s/%s' % (versions, dirname) - log.info('Working on directory: %s', origdir) + origdir = "%s/%s" % (versions, dirname) + log.info("Working on directory: %s", origdir) files = os.listdir(origdir) files.sort() for filename in files: # Delete compiled Python files. - if filename.endswith('.pyc') or filename.endswith('.pyo'): - delete_file('%s/%s' % (origdir, filename)) + if filename.endswith(".pyc") or filename.endswith(".pyo"): + delete_file("%s/%s" % (origdir, filename)) # Delete empty __init__.py files. - origfile = '%s/__init__.py' % origdir + origfile = "%s/__init__.py" % origdir if os.path.exists(origfile) and len(open(origfile).read()) == 0: delete_file(origfile) # Move sql upgrade scripts. - if filename.endswith('.sql'): - version, dbms, operation = filename.split('.', 3)[0:3] - origfile = '%s/%s' % (origdir, filename) + if filename.endswith(".sql"): + version, dbms, operation = filename.split(".", 3)[0:3] + origfile = "%s/%s" % (origdir, filename) # For instance: 2.postgres.upgrade.sql -> # 002_postgres_upgrade.sql - tgtfile = '%s/%03d_%s_%s.sql' % ( - versions, int(version), dbms, operation) + tgtfile = "%s/%03d_%s_%s.sql" % (versions, int(version), dbms, operation) move_file(origfile, tgtfile) # Move Python upgrade script. - pyfile = '%s.py' % dirname - pyfilepath = '%s/%s' % (origdir, pyfile) + pyfile = "%s.py" % dirname + pyfilepath = "%s/%s" % (origdir, pyfile) if os.path.exists(pyfilepath): - tgtfile = '%s/%03d.py' % (versions, int(dirname)) + tgtfile = "%s/%03d.py" % (versions, int(dirname)) move_file(pyfilepath, tgtfile) # Try to remove directory. Will fail if it's not empty. @@ -96,5 +98,5 @@ def main(): migrate_repository(sys.argv[1]) -if __name__ == '__main__': +if __name__ == "__main__": main() diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/pathed.py b/rhodecode/lib/dbmigrate/migrate/versioning/pathed.py index 1639efb1..225e832e 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/pathed.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/pathed.py @@ -1,5 +1,5 @@ """ - A path/directory class. +A path/directory class. """ import os @@ -13,6 +13,7 @@ from rhodecode.lib.dbmigrate.migrate.versioning.util import KeyedInstance log = logging.getLogger(__name__) + class Pathed(KeyedInstance): """ A class associated with a path/directory tree. @@ -20,6 +21,7 @@ class Pathed(KeyedInstance): Only one instance of this class may exist for a particular file; __new__ will return an existing instance if possible """ + parent = None @classmethod @@ -54,7 +56,7 @@ class Pathed(KeyedInstance): # unix basename) # # Treat directories like files... - if path[-1] == '/': + if path[-1] == "/": path = path[:-1] ret = os.path.dirname(path) return ret diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/repository.py b/rhodecode/lib/dbmigrate/migrate/versioning/repository.py index b07d6965..d4223f8d 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/repository.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/repository.py @@ -1,6 +1,7 @@ """ - SQLAlchemy migrate repository management. +SQLAlchemy migrate repository management. """ + import os import shutil import string @@ -17,6 +18,7 @@ from rhodecode.lib.dbmigrate.migrate.versioning.config import * log = logging.getLogger(__name__) + class Changeset(dict): """A collection of changes to be applied to a database. @@ -30,7 +32,7 @@ class Changeset(dict): """ Give a start version; step must be explicitly stated. """ - self.step = k.pop('step', 1) + self.step = k.pop("step", 1) self.start = version.VerNum(start) self.end = self.start for change in changes: @@ -69,18 +71,17 @@ class Changeset(dict): class Repository(pathed.Pathed): """A project's change script repository""" - _config = 'migrate.cfg' - _versions = 'versions' + _config = "migrate.cfg" + _versions = "versions" def __init__(self, path): - log.debug('Loading repository %s...', path) + log.debug("Loading repository %s...", path) self.verify(path) super(Repository, self).__init__(path) self.config = cfgparse.Config(os.path.join(self.path, self._config)) - self.versions = version.Collection(os.path.join(self.path, - self._versions)) - log.debug('Repository %s loaded successfully', path) - log.debug('Config: %r', self.config.to_dict()) + self.versions = version.Collection(os.path.join(self.path, self._versions)) + log.debug("Repository %s loaded successfully", path) + log.debug("Config: %r", self.config.to_dict()) @classmethod def verify(cls, path): @@ -112,17 +113,17 @@ class Repository(pathed.Pathed): """ if options is None: options = {} - options.setdefault('version_table', 'migrate_version') - options.setdefault('repository_id', name) - options.setdefault('required_dbs', []) - options.setdefault('use_timestamp_numbering', False) + options.setdefault("version_table", "migrate_version") + options.setdefault("repository_id", name) + options.setdefault("required_dbs", []) + options.setdefault("use_timestamp_numbering", False) with open(os.path.join(tmpl_dir, cls._config)) as f: tmpl = f.read() ret = TempitaTemplate(tmpl).substitute(options) # cleanup - del options['__template_name__'] + del options["__template_name__"] return ret @@ -130,8 +131,8 @@ class Repository(pathed.Pathed): def create(cls, path, name, **opts): """Create a repository at a specified path""" cls.require_notfound(path) - theme = opts.pop('templates_theme', None) - t_path = opts.pop('templates_path', None) + theme = opts.pop("templates_theme", None) + t_path = opts.pop("templates_path", None) # Create repository tmpl_dir = Template(t_path).get_repository(theme=theme) @@ -139,27 +140,26 @@ class Repository(pathed.Pathed): # Edit config defaults config_text = cls.prepare_config(tmpl_dir, name, options=opts) - with open(os.path.join(path, cls._config), 'w') as fd: + with open(os.path.join(path, cls._config), "w") as fd: fd.write(config_text) - opts['repository_name'] = name + opts["repository_name"] = name # Create a management script - manager = os.path.join(path, 'manage.py') - Repository.create_manage_file(manager, templates_theme=theme, - templates_path=t_path, **opts) + manager = os.path.join(path, "manage.py") + Repository.create_manage_file(manager, templates_theme=theme, templates_path=t_path, **opts) return cls(path) def create_script(self, description, **k): """API to :meth:`migrate.versioning.version.Collection.create_new_python_version`""" - k['use_timestamp_numbering'] = self.use_timestamp_numbering + k["use_timestamp_numbering"] = self.use_timestamp_numbering self.versions.create_new_python_version(description, **k) def create_script_sql(self, database, description, **k): """API to :meth:`migrate.versioning.version.Collection.create_new_sql_version`""" - k['use_timestamp_numbering'] = self.use_timestamp_numbering + k["use_timestamp_numbering"] = self.use_timestamp_numbering self.versions.create_new_sql_version(database, description, **k) @property @@ -170,18 +170,18 @@ class Repository(pathed.Pathed): @property def version_table(self): """Returns version_table name specified in config""" - return self.config.get('db_settings', 'version_table') + return self.config.get("db_settings", "version_table") @property def id(self): """Returns repository id specified in config""" - return self.config.get('db_settings', 'repository_id') + return self.config.get("db_settings", "repository_id") @property def use_timestamp_numbering(self): """Returns use_timestamp_numbering specified in config""" - if self.config.has_option('db_settings', 'use_timestamp_numbering'): - return self.config.getboolean('db_settings', 'use_timestamp_numbering') + if self.config.has_option("db_settings", "use_timestamp_numbering"): + return self.config.getboolean("db_settings", "use_timestamp_numbering") return False def version(self, *p, **k): @@ -215,11 +215,11 @@ class Repository(pathed.Pathed): if start <= end: step = 1 range_mod = 1 - op = 'upgrade' + op = "upgrade" else: step = -1 range_mod = 0 - op = 'downgrade' + op = "downgrade" versions = list(range(int(start) + range_mod, int(end) + range_mod, step)) changes = [self.version(v).script(database, op) for v in versions] @@ -233,11 +233,10 @@ class Repository(pathed.Pathed): :param file_: Destination file to be written :param opts: Options that are passed to :func:`migrate.versioning.shell.main` """ - mng_file = Template(opts.pop('templates_path', None))\ - .get_manage(theme=opts.pop('templates_theme', None)) + mng_file = Template(opts.pop("templates_path", None)).get_manage(theme=opts.pop("templates_theme", None)) with open(mng_file) as f: tmpl = f.read() - with open(file_, 'w') as fd: + with open(file_, "w") as fd: fd.write(TempitaTemplate(tmpl).substitute(opts)) diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/schema.py b/rhodecode/lib/dbmigrate/migrate/versioning/schema.py index f22a1e7d..8fe8b458 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/schema.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/schema.py @@ -1,10 +1,11 @@ """ - Database schema version management. +Database schema version management. """ + import sys import logging -from sqlalchemy import (Table, Column, MetaData, String, Text, Integer, create_engine) +from sqlalchemy import Table, Column, MetaData, String, Text, Integer, create_engine from sqlalchemy.sql import and_ from sqlalchemy import exc as sa_exceptions from sqlalchemy.sql import bindparam @@ -33,25 +34,23 @@ class ControlledSchema(object): def __eq__(self, other): """Compare two schemas by repositories and versions""" - return (self.repository is other.repository \ - and self.version == other.version) + return self.repository is other.repository and self.version == other.version def load(self): """Load controlled schema version info from DB""" tname = self.repository.version_table try: - if not hasattr(self, 'table') or self.table is None: - self.table = Table(tname, self.meta, autoload=True) + if not hasattr(self, "table") or self.table is None: + self.table = Table(tname, self.meta, autoload=True) - result = self.engine.execute(self.table.select( - self.table.c.repository_id == str(self.repository.id))) + result = self.engine.execute(self.table.select(self.table.c.repository_id == str(self.repository.id))) data = list(result)[0] except: cls, exc, tb = sys.exc_info() raise exceptions.DatabaseNotControlledError(exc.__str__()).with_traceback(tb) - self.version = data['version'] + self.version = data["version"] return data def drop(self): @@ -66,7 +65,7 @@ class ControlledSchema(object): else: try: self.table.drop() - except (sa_exceptions.SQLError): + except sa_exceptions.SQLError: raise exceptions.DatabaseNotControlledError(str(self.table)) def changeset(self, version=None): @@ -85,8 +84,7 @@ class ControlledSchema(object): endver = ver + step # Current database version must be correct! Don't run if corrupt! if self.version != startver: - raise exceptions.InvalidVersionError("%s is not %s" % \ - (self.version, startver)) + raise exceptions.InvalidVersionError("%s is not %s" % (self.version, startver)) # Run the change change.run(self.engine, step) @@ -96,8 +94,9 @@ class ControlledSchema(object): def update_repository_table(self, startver, endver): """Update version_table with new information""" - update = self.table.update(and_(self.table.c.version == int(startver), - self.table.c.repository_id == str(self.repository.id))) + update = self.table.update( + and_(self.table.c.version == int(startver), self.table.c.repository_id == str(self.repository.id)) + ) self.engine.execute(update, version=int(endver)) def upgrade(self, version=None): @@ -116,8 +115,8 @@ class ControlledSchema(object): diff = schemadiff.getDiffOfModelAgainstDatabase( model, self.engine, excludeTables=[self.repository.version_table] - ) - genmodel.ModelGenerator(diff,self.engine).runB2A() + ) + genmodel.ModelGenerator(diff, self.engine).runB2A() self.update_repository_table(self.version, int(self.repository.latest)) @@ -171,10 +170,12 @@ class ControlledSchema(object): meta = MetaData(engine) table = Table( - tname, meta, - Column('repository_id', String(250), primary_key=True), - Column('repository_path', Text), - Column('version', Integer), ) + tname, + meta, + Column("repository_id", String(250), primary_key=True), + Column("repository_path", Text), + Column("version", Integer), + ) # there can be multiple repositories/schemas in the same db if not table.exists(): @@ -187,10 +188,9 @@ class ControlledSchema(object): raise exceptions.DatabaseAlreadyControlledError # Insert data - engine.execute(table.insert().values( - repository_id=repository.id, - repository_path=repository.path, - version=int(version))) + engine.execute( + table.insert().values(repository_id=repository.id, repository_path=repository.path, version=int(version)) + ) return table @classmethod @@ -202,8 +202,7 @@ class ControlledSchema(object): repository = Repository(repository) model = load_model(model) - diff = schemadiff.getDiffOfModelAgainstDatabase( - model, engine, excludeTables=[repository.version_table]) + diff = schemadiff.getDiffOfModelAgainstDatabase(model, engine, excludeTables=[repository.version_table]) return diff @classmethod @@ -214,7 +213,5 @@ class ControlledSchema(object): if isinstance(repository, str): repository = Repository(repository) - diff = schemadiff.getDiffOfModelAgainstDatabase( - MetaData(), engine, excludeTables=[repository.version_table] - ) + diff = schemadiff.getDiffOfModelAgainstDatabase(MetaData(), engine, excludeTables=[repository.version_table]) return genmodel.ModelGenerator(diff, engine, declarative).genBDefinition() diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/schemadiff.py b/rhodecode/lib/dbmigrate/migrate/versioning/schemadiff.py index 92d08d3b..44145b9f 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/schemadiff.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/schemadiff.py @@ -1,5 +1,5 @@ """ - Schema differencing support. +Schema differencing support. """ import logging @@ -23,14 +23,11 @@ def getDiffOfModelAgainstDatabase(metadata, engine, excludeTables=None): # sqlite will include a dynamically generated 'sqlite_sequence' table if # there are autoincrement sequences in the database; this should not be # compared. - if engine.dialect.name == 'sqlite': - if 'sqlite_sequence' in db_metadata.tables: - db_metadata.remove(db_metadata.tables['sqlite_sequence']) + if engine.dialect.name == "sqlite": + if "sqlite_sequence" in db_metadata.tables: + db_metadata.remove(db_metadata.tables["sqlite_sequence"]) - return SchemaDiff(metadata, db_metadata, - labelA='model', - labelB='database', - excludeTables=excludeTables) + return SchemaDiff(metadata, db_metadata, labelA="model", labelB="database", excludeTables=excludeTables) def getDiffOfModelAgainstModel(metadataA, metadataB, excludeTables=None): @@ -71,7 +68,7 @@ class ColDiff(object): diff = False - def __init__(self,col_A,col_B): + def __init__(self, col_A, col_B): self.col_A = col_A self.col_B = col_B @@ -85,16 +82,16 @@ class ColDiff(object): self.diff = True return - if isinstance(self.type_A,Float) or isinstance(self.type_B,Float): - if not (isinstance(self.type_A,Float) and isinstance(self.type_B,Float)): - self.diff=True + if isinstance(self.type_A, Float) or isinstance(self.type_B, Float): + if not (isinstance(self.type_A, Float) and isinstance(self.type_B, Float)): + self.diff = True return - for attr in ('precision','scale','length'): - A = getattr(self.type_A,attr,None) - B = getattr(self.type_B,attr,None) - if not (A is None or B is None) and A!=B: - self.diff=True + for attr in ("precision", "scale", "length"): + A = getattr(self.type_A, attr, None) + B = getattr(self.type_B, attr, None) + if not (A is None or B is None) and A != B: + self.diff = True return def __nonzero__(self): @@ -126,21 +123,19 @@ class TableDiff(object): It maps column names to a :class:`ColDiff` objects describing the differences found. """ + __slots__ = ( - 'columns_missing_from_A', - 'columns_missing_from_B', - 'columns_different', - ) + "columns_missing_from_A", + "columns_missing_from_B", + "columns_different", + ) def __nonzero__(self): - return bool( - self.columns_missing_from_A or - self.columns_missing_from_B or - self.columns_different - ) + return bool(self.columns_missing_from_A or self.columns_missing_from_B or self.columns_different) __bool__ = __nonzero__ + class SchemaDiff(object): """ Compute the difference between two :class:`~sqlalchemy.schema.MetaData` @@ -189,30 +184,20 @@ class SchemaDiff(object): differences found. """ - def __init__(self, - metadataA, metadataB, - labelA='metadataA', - labelB='metadataB', - excludeTables=None): - + def __init__(self, metadataA, metadataB, labelA="metadataA", labelB="metadataB", excludeTables=None): self.metadataA, self.metadataB = metadataA, metadataB self.labelA, self.labelB = labelA, labelB - self.label_width = max(len(labelA),len(labelB)) + self.label_width = max(len(labelA), len(labelB)) excludeTables = set(excludeTables or []) A_table_names = set(metadataA.tables.keys()) B_table_names = set(metadataB.tables.keys()) - self.tables_missing_from_A = sorted( - B_table_names - A_table_names - excludeTables - ) - self.tables_missing_from_B = sorted( - A_table_names - B_table_names - excludeTables - ) + self.tables_missing_from_A = sorted(B_table_names - A_table_names - excludeTables) + self.tables_missing_from_B = sorted(A_table_names - B_table_names - excludeTables) self.tables_different = {} for table_name in A_table_names.intersection(B_table_names): - td = TableDiff() A_table = metadataA.tables[table_name] @@ -221,79 +206,57 @@ class SchemaDiff(object): A_column_names = set(A_table.columns.keys()) B_column_names = set(B_table.columns.keys()) - td.columns_missing_from_A = sorted( - B_column_names - A_column_names - ) + td.columns_missing_from_A = sorted(B_column_names - A_column_names) - td.columns_missing_from_B = sorted( - A_column_names - B_column_names - ) + td.columns_missing_from_B = sorted(A_column_names - B_column_names) td.columns_different = {} for col_name in A_column_names.intersection(B_column_names): - - cd = ColDiff( - A_table.columns.get(col_name), - B_table.columns.get(col_name) - ) + cd = ColDiff(A_table.columns.get(col_name), B_table.columns.get(col_name)) if cd: - td.columns_different[col_name]=cd + td.columns_different[col_name] = cd # XXX - index and constraint differences should # be checked for here if td: - self.tables_different[table_name]=td + self.tables_different[table_name] = td def __str__(self): - """ Summarize differences. """ + """Summarize differences.""" out = [] - column_template =' %%%is: %%r' % self.label_width + column_template = " %%%is: %%r" % self.label_width - for names,label in ( - (self.tables_missing_from_A,self.labelA), - (self.tables_missing_from_B,self.labelB), - ): + for names, label in ( + (self.tables_missing_from_A, self.labelA), + (self.tables_missing_from_B, self.labelB), + ): if names: - out.append( - ' tables missing from %s: %s' % ( - label,', '.join(sorted(names)) - ) - ) + out.append(" tables missing from %s: %s" % (label, ", ".join(sorted(names)))) - for name,td in sorted(self.tables_different.items()): - out.append( - ' table with differences: %s' % name - ) - for names,label in ( - (td.columns_missing_from_A,self.labelA), - (td.columns_missing_from_B,self.labelB), - ): + for name, td in sorted(self.tables_different.items()): + out.append(" table with differences: %s" % name) + for names, label in ( + (td.columns_missing_from_A, self.labelA), + (td.columns_missing_from_B, self.labelB), + ): if names: - out.append( - ' %s missing these columns: %s' % ( - label,', '.join(sorted(names)) - ) - ) - for name,cd in list(td.columns_different.items()): - out.append(' column with differences: %s' % name) - out.append(column_template % (self.labelA,cd.col_A)) - out.append(column_template % (self.labelB,cd.col_B)) + out.append(" %s missing these columns: %s" % (label, ", ".join(sorted(names)))) + for name, cd in list(td.columns_different.items()): + out.append(" column with differences: %s" % name) + out.append(column_template % (self.labelA, cd.col_A)) + out.append(column_template % (self.labelB, cd.col_B)) if out: - out.insert(0, 'Schema diffs:') - return '\n'.join(out) + out.insert(0, "Schema diffs:") + return "\n".join(out) else: - return 'No schema diffs' + return "No schema diffs" def __len__(self): """ Used in bool evaluation, return of 0 means no diffs. """ - return ( - len(self.tables_missing_from_A) + - len(self.tables_missing_from_B) + - len(self.tables_different) - ) + return len(self.tables_missing_from_A) + len(self.tables_missing_from_B) + len(self.tables_different) diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/script/base.py b/rhodecode/lib/dbmigrate/migrate/versioning/script/base.py index ca1c9927..078e2501 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/script/base.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/script/base.py @@ -9,6 +9,7 @@ from rhodecode.lib.dbmigrate.migrate.versioning import pathed log = logging.getLogger(__name__) + class BaseScript(pathed.Pathed): """Base class for other types of scripts. All scripts have the following properties: @@ -21,13 +22,13 @@ class BaseScript(pathed.Pathed): The operations defined by the script: upgrade(), downgrade() or both. Returns a tuple of operations. Can also check for an operation with ex. script.operation(Script.ops.up) - """ # TODO: sphinxfy this and implement it correctly + """ # TODO: sphinxfy this and implement it correctly def __init__(self, path): - log.debug('Loading script %s...', path) + log.debug("Loading script %s...", path) self.verify(path) super(BaseScript, self).__init__(path) - log.debug('Script %s loaded successfully', path) + log.debug("Script %s loaded successfully", path) @classmethod def verify(cls, path): diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/script/py.py b/rhodecode/lib/dbmigrate/migrate/versioning/script/py.py index 68eda5ba..61f1ec13 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/script/py.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/script/py.py @@ -16,7 +16,7 @@ from rhodecode.lib.dbmigrate.migrate.versioning.util import import_path, load_mo from rhodecode.lib.dbmigrate.migrate.exceptions import MigrateDeprecationWarning, InvalidScriptError, ScriptError log = logging.getLogger(__name__) -__all__ = ['PythonScript'] +__all__ = ["PythonScript"] class PythonScript(base.BaseScript): @@ -29,14 +29,13 @@ class PythonScript(base.BaseScript): :returns: :class:`PythonScript instance `""" cls.require_notfound(path) - src = Template(opts.pop('templates_path', None)).get_script(theme=opts.pop('templates_theme', None)) + src = Template(opts.pop("templates_path", None)).get_script(theme=opts.pop("templates_theme", None)) shutil.copy(src, path) return cls(path) @classmethod - def make_update_script_for_model(cls, engine, oldmodel, - model, repository, **opts): + def make_update_script_for_model(cls, engine, oldmodel, model, repository, **opts): """Create a migration script based on difference between two SA models. :param repository: path to migrate repository @@ -54,32 +53,29 @@ class PythonScript(base.BaseScript): if isinstance(repository, str): # oh dear, an import cycle! from rhodecode.lib.dbmigrate.migrate.versioning.repository import Repository + repository = Repository(repository) oldmodel = load_model(oldmodel) model = load_model(model) # Compute differences. - diff = schemadiff.getDiffOfModelAgainstModel( - model, - oldmodel, - excludeTables=[repository.version_table]) + diff = schemadiff.getDiffOfModelAgainstModel(model, oldmodel, excludeTables=[repository.version_table]) # TODO: diff can be False (there is no difference?) - decls, upgradeCommands, downgradeCommands = \ - genmodel.ModelGenerator(diff,engine).genB2AMigration() + decls, upgradeCommands, downgradeCommands = genmodel.ModelGenerator(diff, engine).genB2AMigration() # Store differences into file. - src = Template(opts.pop('templates_path', None)).get_script(opts.pop('templates_theme', None)) + src = Template(opts.pop("templates_path", None)).get_script(opts.pop("templates_theme", None)) with open(src) as f: contents = f.read() # generate source - search = 'def upgrade(migrate_engine):' - contents = contents.replace(search, '\n\n'.join((decls, search)), 1) + search = "def upgrade(migrate_engine):" + contents = contents.replace(search, "\n\n".join((decls, search)), 1) if upgradeCommands: - contents = contents.replace(' pass', upgradeCommands, 1) + contents = contents.replace(" pass", upgradeCommands, 1) if downgradeCommands: - contents = contents.replace(' pass', downgradeCommands, 1) + contents = contents.replace(" pass", downgradeCommands, 1) return contents @classmethod @@ -96,7 +92,7 @@ class PythonScript(base.BaseScript): try: assert callable(module.upgrade) except Exception as e: - raise InvalidScriptError(path + ': %s' % str(e)) + raise InvalidScriptError(path + ": %s" % str(e)) return module def preview_sql(self, url, step, **args): @@ -106,12 +102,12 @@ class PythonScript(base.BaseScript): :returns: SQL file """ buf = StringIO() - args['engine_arg_strategy'] = 'mock' - args['engine_arg_executor'] = lambda s, p = '': buf.write(str(s) + p) + args["engine_arg_strategy"] = "mock" + args["engine_arg_executor"] = lambda s, p="": buf.write(str(s) + p) @with_engine def go(url, step, **kw): - engine = kw.pop('engine') + engine = kw.pop("engine") self.run(engine, step) return buf.getvalue() @@ -127,9 +123,9 @@ class PythonScript(base.BaseScript): :type step: int """ if step > 0: - op = 'upgrade' + op = "upgrade" elif step < 0: - op = 'downgrade' + op = "downgrade" else: raise ScriptError("%d is not a valid step" % step) @@ -138,8 +134,7 @@ class PythonScript(base.BaseScript): # check for old way of using engine if not inspect.getargspec(script_func)[0]: - raise TypeError("upgrade/downgrade functions must accept engine" - " parameter (since version 0.5.4)") + raise TypeError("upgrade/downgrade functions must accept engine parameter (since version 0.5.4)") script_func(engine) @@ -148,7 +143,7 @@ class PythonScript(base.BaseScript): """Calls :meth:`migrate.versioning.script.py.verify_module` and returns it. """ - if not hasattr(self, '_module'): + if not hasattr(self, "_module"): self._module = self.verify_module(self.path) return self._module diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/script/sql.py b/rhodecode/lib/dbmigrate/migrate/versioning/script/sql.py index b0e102ee..b07e6607 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/script/sql.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/script/sql.py @@ -9,6 +9,7 @@ from rhodecode.lib.dbmigrate.migrate.versioning.template import Template log = logging.getLogger(__name__) + class SqlScript(base.BaseScript): """A file containing plain SQL statements.""" @@ -19,7 +20,7 @@ class SqlScript(base.BaseScript): :returns: :class:`SqlScript instance `""" cls.require_notfound(path) - src = Template(opts.pop('templates_path', None)).get_sql_script(theme=opts.pop('templates_theme', None)) + src = Template(opts.pop("templates_path", None)).get_sql_script(theme=opts.pop("templates_theme", None)) shutil.copy(src, path) return cls(path) @@ -37,7 +38,7 @@ class SqlScript(base.BaseScript): # HACK: SQLite doesn't allow multiple statements through # its execute() method, but it provides executescript() instead dbapi = conn.engine.raw_connection() - if executemany and getattr(dbapi, 'executescript', None): + if executemany and getattr(dbapi, "executescript", None): dbapi.executescript(text) else: conn.execute(text) diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/shell.py b/rhodecode/lib/dbmigrate/migrate/versioning/shell.py index da03c31d..cc7f54a6 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/shell.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/shell.py @@ -15,21 +15,23 @@ from rhodecode.lib.dbmigrate.migrate.versioning.util import asbool alias = { - 's': api.script, - 'vc': api.version_control, - 'dbv': api.db_version, - 'v': api.version, + "s": api.script, + "vc": api.version_control, + "dbv": api.db_version, + "v": api.version, } + def alias_setup(): global alias for key, val in list(alias.items()): setattr(api, key, val) + + alias_setup() class PassiveOptionParser(OptionParser): - def _process_args(self, largs, rargs, values): """little hack to support all --some_option=value parameters""" @@ -42,7 +44,7 @@ class PassiveOptionParser(OptionParser): # if parser does not know about the option # pass it along (make it anonymous) try: - opt = arg.split('=', 1)[0] + opt = arg.split("=", 1)[0] self._match_long_opt(opt) except BadOptionError: largs.append(arg) @@ -55,6 +57,7 @@ class PassiveOptionParser(OptionParser): largs.append(arg) del rargs[0] + def main(argv=None, **kwargs): """Shell interface to :mod:`migrate.versioning.api`. @@ -77,20 +80,26 @@ def main(argv=None, **kwargs): %s Enter "%%prog help COMMAND" for information on a particular command. - """ % '\n\t'.join(["%s - %s" % (command.ljust(28), api.command_desc.get(command)) for command in commands]) + """ % "\n\t".join(["%s - %s" % (command.ljust(28), api.command_desc.get(command)) for command in commands]) parser = PassiveOptionParser(usage=usage) - parser.add_option("-d", "--debug", - action="store_true", - dest="debug", - default=False, - help="Shortcut to turn on DEBUG mode for logging") - parser.add_option("-q", "--disable_logging", - action="store_true", - dest="disable_logging", - default=False, - help="Use this option to disable logging configuration") - help_commands = ['help', '-h', '--help'] + parser.add_option( + "-d", + "--debug", + action="store_true", + dest="debug", + default=False, + help="Shortcut to turn on DEBUG mode for logging", + ) + parser.add_option( + "-q", + "--disable_logging", + action="store_true", + dest="disable_logging", + default=False, + help="Use this option to disable logging configuration", + ) + help_commands = ["help", "-h", "--help"] HELP = False try: @@ -103,17 +112,13 @@ def main(argv=None, **kwargs): return command_func = getattr(api, command, None) - if command_func is None or command.startswith('_'): + if command_func is None or command.startswith("_"): parser.error("Invalid command %s" % command) parser.set_usage(inspect.getdoc(command_func)) f_args, f_varargs, f_kwargs, f_defaults = inspect.getargspec(command_func) for arg in f_args: - parser.add_option( - "--%s" % arg, - dest=arg, - action='store', - type="string") + parser.add_option("--%s" % arg, dest=arg, action="store", type="string") # display help of the current command if HELP: @@ -125,10 +130,10 @@ def main(argv=None, **kwargs): # override kwargs with anonymous parameters override_kwargs = {} for arg in list(args): - if arg.startswith('--'): + if arg.startswith("--"): args.remove(arg) - if '=' in arg: - opt, value = arg[2:].split('=', 1) + if "=" in arg: + opt, value = arg[2:].split("=", 1) else: opt = arg[2:] value = True @@ -152,8 +157,7 @@ def main(argv=None, **kwargs): try: kw = f_required.pop(0) except IndexError: - parser.error("Too many arguments for command %s: %s" % (command, - arg)) + parser.error("Too many arguments for command %s: %s" % (command, arg)) kwargs[kw] = arg # apply overrides @@ -164,7 +168,7 @@ def main(argv=None, **kwargs): kwargs.setdefault(key, value) # configure logging - if not asbool(kwargs.pop('disable_logging', False)): + if not asbool(kwargs.pop("disable_logging", False)): # filter to log =< INFO into stdout and rest to stderr class SingleLevelFilter(logging.Filter): def __init__(self, min=None, max=None): @@ -196,12 +200,11 @@ def main(argv=None, **kwargs): num_defaults = len(f_defaults) except TypeError: num_defaults = 0 - f_args_default = f_args[len(f_args) - num_defaults:] + f_args_default = f_args[len(f_args) - num_defaults :] required = list(set(f_required) - set(f_args_default)) required.sort() if required: - parser.error("Not enough arguments for command %s: %s not specified" \ - % (command, ', '.join(required))) + parser.error("Not enough arguments for command %s: %s not specified" % (command, ", ".join(required))) # handle command try: @@ -211,5 +214,6 @@ def main(argv=None, **kwargs): except (exceptions.UsageError, exceptions.KnownError) as e: parser.error(e.args[0]) + if __name__ == "__main__": main() diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/template.py b/rhodecode/lib/dbmigrate/migrate/versioning/template.py index 7beddd37..24b3000e 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/template.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/template.py @@ -13,6 +13,7 @@ from rhodecode.lib.dbmigrate.migrate.versioning import pathed class Collection(pathed.Pathed): """A collection of templates of a specific type""" + _mask = None def get_path(self, file): @@ -20,16 +21,20 @@ class Collection(pathed.Pathed): class RepositoryCollection(Collection): - _mask = '%s' + _mask = "%s" + class ScriptCollection(Collection): - _mask = '%s.py_tmpl' + _mask = "%s.py_tmpl" + class ManageCollection(Collection): - _mask = '%s.py_tmpl' + _mask = "%s.py_tmpl" + class SQLScriptCollection(Collection): - _mask = '%s.py_tmpl' + _mask = "%s.py_tmpl" + class Template(pathed.Pathed): """Finds the paths/packages of various Migrate templates. @@ -37,7 +42,8 @@ class Template(pathed.Pathed): :param path: Templates are loaded from rhodecode.lib.dbmigrate.migrate package if `path` is not provided. """ - pkg = 'rhodecode.lib.dbmigrate.migrate.versioning.templates' + + pkg = "rhodecode.lib.dbmigrate.migrate.versioning.templates" def __new__(cls, path=None): if path is None: @@ -48,20 +54,20 @@ class Template(pathed.Pathed): if path is None: path = Template._find_path(self.pkg) super(Template, self).__init__(path) - self.repository = RepositoryCollection(os.path.join(path, 'repository')) - self.script = ScriptCollection(os.path.join(path, 'script')) - self.manage = ManageCollection(os.path.join(path, 'manage')) - self.sql_script = SQLScriptCollection(os.path.join(path, 'sql_script')) + self.repository = RepositoryCollection(os.path.join(path, "repository")) + self.script = ScriptCollection(os.path.join(path, "script")) + self.manage = ManageCollection(os.path.join(path, "manage")) + self.sql_script = SQLScriptCollection(os.path.join(path, "sql_script")) @classmethod def _find_path(cls, pkg): """Returns absolute path to dotted python package.""" - tmp_pkg = pkg.rsplit('.', 1) + tmp_pkg = pkg.rsplit(".", 1) if len(tmp_pkg) != 1: return resource_filename(tmp_pkg[0], tmp_pkg[1]) else: - return resource_filename(tmp_pkg[0], '') + return resource_filename(tmp_pkg[0], "") def _get_item(self, collection, theme=None): """Locates and returns collection. @@ -72,22 +78,22 @@ class Template(pathed.Pathed): :rtype: str, str """ item = getattr(self, collection) - theme_mask = getattr(item, '_mask') - theme = theme_mask % (theme or 'default') + theme_mask = getattr(item, "_mask") + theme = theme_mask % (theme or "default") return item.get_path(theme) def get_repository(self, *a, **kw): """Calls self._get_item('repository', *a, **kw)""" - return self._get_item('repository', *a, **kw) + return self._get_item("repository", *a, **kw) def get_script(self, *a, **kw): """Calls self._get_item('script', *a, **kw)""" - return self._get_item('script', *a, **kw) + return self._get_item("script", *a, **kw) def get_sql_script(self, *a, **kw): """Calls self._get_item('sql_script', *a, **kw)""" - return self._get_item('sql_script', *a, **kw) + return self._get_item("sql_script", *a, **kw) def get_manage(self, *a, **kw): """Calls self._get_item('manage', *a, **kw)""" - return self._get_item('manage', *a, **kw) + return self._get_item("manage", *a, **kw) diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/util/__init__.py b/rhodecode/lib/dbmigrate/migrate/versioning/util/__init__.py index e286c0ab..61ebc925 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/util/__init__.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/util/__init__.py @@ -28,23 +28,26 @@ def load_model(dotted_name): """ if isinstance(dotted_name, str): - if ':' not in dotted_name: + if ":" not in dotted_name: # backwards compatibility - warnings.warn('model should be in form of module.model:User ' - 'and not module.model.User', exceptions.MigrateDeprecationWarning) - dotted_name = ':'.join(dotted_name.rsplit('.', 1)) - return EntryPoint.parse('x=%s' % dotted_name).load(False) + warnings.warn( + "model should be in form of module.model:User and not module.model.User", + exceptions.MigrateDeprecationWarning, + ) + dotted_name = ":".join(dotted_name.rsplit(".", 1)) + return EntryPoint.parse("x=%s" % dotted_name).load(False) else: # Assume it's already loaded. return dotted_name + def asbool(obj): """Do everything to use object as bool""" if isinstance(obj, str): obj = obj.strip().lower() - if obj in ['true', 'yes', 'on', 'y', 't', '1']: + if obj in ["true", "yes", "on", "y", "t", "1"]: return True - elif obj in ['false', 'no', 'off', 'n', 'f', '0']: + elif obj in ["false", "no", "off", "n", "f", "0"]: return False else: raise ValueError("String is not true/false: %r" % obj) @@ -53,6 +56,7 @@ def asbool(obj): else: raise ValueError("String is not true/false: %r" % obj) + def guess_obj_type(obj): """Do everything to guess object type from string @@ -79,6 +83,7 @@ def guess_obj_type(obj): else: return obj + @decorator def catch_known_errors(f, *a, **kw): """Decorator that catches known api errors @@ -91,6 +96,7 @@ def catch_known_errors(f, *a, **kw): except exceptions.PathFoundError as e: raise exceptions.KnownError("The path %s already exists" % e.args[0]) + def construct_engine(engine, **opts): """.. versionadded:: 0.5.4 @@ -117,29 +123,31 @@ def construct_engine(engine, **opts): raise ValueError("you need to pass either an existing engine or a database uri") # get options for create_engine - if opts.get('engine_dict') and isinstance(opts['engine_dict'], dict): - kwargs = opts['engine_dict'] + if opts.get("engine_dict") and isinstance(opts["engine_dict"], dict): + kwargs = opts["engine_dict"] else: kwargs = {} # DEPRECATED: handle echo the old way - echo = asbool(opts.get('echo', False)) + echo = asbool(opts.get("echo", False)) if echo: warnings.warn( 'echo=True parameter is deprecated, pass engine_arg_echo=True or engine_dict={"echo": True}', - exceptions.MigrateDeprecationWarning) - kwargs['echo'] = echo + exceptions.MigrateDeprecationWarning, + ) + kwargs["echo"] = echo # parse keyword arguments for key, value in list(opts.items()): - if key.startswith('engine_arg_'): + if key.startswith("engine_arg_"): kwargs[key[11:]] = guess_obj_type(value) - log.debug('Constructing engine') + log.debug("Constructing engine") # TODO: return create_engine(engine, poolclass=StaticPool, **kwargs) # seems like 0.5.x branch does not work with engine.dispose and staticpool return create_engine(engine, **kwargs) + @decorator def with_engine(f, *a, **kw): """Decorator for :mod:`migrate.versioning.api` functions @@ -156,20 +164,21 @@ def with_engine(f, *a, **kw): engine = construct_engine(url, **kw) try: - kw['engine'] = engine + kw["engine"] = engine return f(*a, **kw) finally: if isinstance(engine, Engine) and engine is not url: - log.debug('Disposing SQLAlchemy engine %s', engine) + log.debug("Disposing SQLAlchemy engine %s", engine) engine.dispose() class Memoize: """Memoize(fn) - an instance which acts like fn but memoizes its arguments - Will only work on functions with non-mutable arguments + Will only work on functions with non-mutable arguments - ActiveState Code 52201 + ActiveState Code 52201 """ + def __init__(self, fn): self.fn = fn self.memo = {} diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/util/importpath.py b/rhodecode/lib/dbmigrate/migrate/versioning/util/importpath.py index 0f38087a..3bf1bebe 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/util/importpath.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/util/importpath.py @@ -2,15 +2,16 @@ import os import sys import importlib + def import_path(fullpath): - """ Import a file with full path specification. Allows one to - import from anywhere, something __import__ does not do. + """Import a file with full path specification. Allows one to + import from anywhere, something __import__ does not do. """ # http://zephyrfalcon.org/weblog/arch_d7_2002_08_31.html path, filename = os.path.split(fullpath) filename, ext = os.path.splitext(filename) sys.path.append(path) module = __import__(filename) - importlib.reload(module) # Might be out of date during tests + importlib.reload(module) # Might be out of date during tests del sys.path[-1] return module diff --git a/rhodecode/lib/dbmigrate/migrate/versioning/version.py b/rhodecode/lib/dbmigrate/migrate/versioning/version.py index 69f157ec..5e3d3fa8 100644 --- a/rhodecode/lib/dbmigrate/migrate/versioning/version.py +++ b/rhodecode/lib/dbmigrate/migrate/versioning/version.py @@ -13,6 +13,7 @@ from datetime import datetime log = logging.getLogger(__name__) + class VerNum(object): """A version number that behaves like a string and int at the same time""" @@ -25,7 +26,7 @@ class VerNum(object): ret = cls._instances[val] return ret - def __init__(self,value): + def __init__(self, value): self.value = str(int(value)) if self < 0: raise ValueError("Version number cannot be negative") @@ -74,7 +75,7 @@ class VerNum(object): class Collection(pathed.Pathed): """A collection of versioning scripts in a repository""" - FILENAME_WITH_VERSION = re.compile(r'^(\d{3,}).*') + FILENAME_WITH_VERSION = re.compile(r"^(\d{3,}).*") def __init__(self, path): """Collect current version scripts in repository @@ -84,11 +85,13 @@ class Collection(pathed.Pathed): # Create temporary list of files, allowing skipped version numbers. files = os.listdir(path) - if '1' in files: + if "1" in files: # deprecation - raise Exception('It looks like you have a repository in the old ' - 'format (with directories for each version). ' - 'Please convert repository before proceeding.') + raise Exception( + "It looks like you have a repository in the old " + "format (with directories for each version). " + "Please convert repository before proceeding." + ) tempVersions = {} for filename in files: @@ -112,22 +115,22 @@ class Collection(pathed.Pathed): def _next_ver_num(self, use_timestamp_numbering): if use_timestamp_numbering is True: - return VerNum(int(datetime.utcnow().strftime('%Y%m%d%H%M%S'))) + return VerNum(int(datetime.utcnow().strftime("%Y%m%d%H%M%S"))) else: return self.latest + 1 def create_new_python_version(self, description, **k): """Create Python files for new version""" - ver = self._next_ver_num(k.pop('use_timestamp_numbering', False)) + ver = self._next_ver_num(k.pop("use_timestamp_numbering", False)) extra = str_to_filename(description) if extra: - if extra == '_': - extra = '' - elif not extra.startswith('_'): - extra = '_%s' % extra + if extra == "_": + extra = "" + elif not extra.startswith("_"): + extra = "_%s" % extra - filename = '%03d%s.py' % (ver, extra) + filename = "%03d%s.py" % (ver, extra) filepath = self._version_path(filename) script.PythonScript.create(filepath, **k) @@ -135,20 +138,20 @@ class Collection(pathed.Pathed): def create_new_sql_version(self, database, description, **k): """Create SQL files for new version""" - ver = self._next_ver_num(k.pop('use_timestamp_numbering', False)) + ver = self._next_ver_num(k.pop("use_timestamp_numbering", False)) self.versions[ver] = Version(ver, self.path, []) extra = str_to_filename(description) if extra: - if extra == '_': - extra = '' - elif not extra.startswith('_'): - extra = '_%s' % extra + if extra == "_": + extra = "" + elif not extra.startswith("_"): + extra = "_%s" % extra # Create new files. - for op in ('upgrade', 'downgrade'): - filename = '%03d%s_%s_%s.sql' % (ver, extra, database, op) + for op in ("upgrade", "downgrade"): + filename = "%03d%s_%s_%s.sql" % (ver, extra, database, op) filepath = self._version_path(filename) script.SqlScript.create(filepath, **k) self.versions[ver].add_script(filepath) @@ -191,7 +194,7 @@ class Version(object): def script(self, database=None, operation=None): """Returns SQL or Python Script""" - for db in (database, 'default'): + for db in (database, "default"): # Try to return a .sql script first try: return self.sql[db][operation] @@ -201,8 +204,7 @@ class Version(object): # TODO: maybe add force Python parameter? ret = self.python - assert ret is not None, \ - "There is no script for %d version" % self.version + assert ret is not None, "There is no script for %d version" % self.version return ret def add_script(self, path): @@ -212,58 +214,62 @@ class Version(object): elif path.endswith(Extensions.sql): self._add_script_sql(path) - SQL_FILENAME = re.compile(r'^.*\.sql') + SQL_FILENAME = re.compile(r"^.*\.sql") def _add_script_sql(self, path): basename = os.path.basename(path) match = self.SQL_FILENAME.match(basename) if match: - basename = basename.replace('.sql', '') - parts = basename.split('_') + basename = basename.replace(".sql", "") + parts = basename.split("_") if len(parts) < 3: raise exceptions.ScriptError( - "Invalid SQL script name %s " % basename + \ - "(needs to be ###_description_database_operation.sql)") + "Invalid SQL script name %s " % basename + "(needs to be ###_description_database_operation.sql)" + ) version = parts[0] op = parts[-1] # NOTE(mriedem): check for ibm_db_sa as the database in the name - if 'ibm_db_sa' in basename: + if "ibm_db_sa" in basename: if len(parts) == 6: - dbms = '_'.join(parts[-4: -1]) + dbms = "_".join(parts[-4:-1]) else: raise exceptions.ScriptError( "Invalid ibm_db_sa SQL script name '%s'; " "(needs to be " - "###_description_ibm_db_sa_operation.sql)" % basename) + "###_description_ibm_db_sa_operation.sql)" % basename + ) else: dbms = parts[-2] else: raise exceptions.ScriptError( - "Invalid SQL script name %s " % basename + \ - "(needs to be ###_description_database_operation.sql)") + "Invalid SQL script name %s " % basename + "(needs to be ###_description_database_operation.sql)" + ) # File the script into a dictionary self.sql.setdefault(dbms, {})[op] = script.SqlScript(path) def _add_script_py(self, path): if self.python is not None: - raise exceptions.ScriptError('You can only have one Python script ' - 'per version, but you have: %s and %s' % (self.python, path)) + raise exceptions.ScriptError( + "You can only have one Python script per version, but you have: %s and %s" % (self.python, path) + ) self.python = script.PythonScript(path) class Extensions: """A namespace for file extensions""" - py = 'py' - sql = 'sql' + + py = "py" + sql = "sql" + def str_to_filename(s): """Replaces spaces, (double and single) quotes and double underscores to underscores """ - s = s.replace(' ', '_').replace('"', '_').replace("'", '_').replace(".", "_") - while '__' in s: - s = s.replace('__', '_') + s = s.replace(" ", "_").replace('"', "_").replace("'", "_").replace(".", "_") + while "__" in s: + s = s.replace("__", "_") return s diff --git a/rhodecode/lib/dbmigrate/schema/__init__.py b/rhodecode/lib/dbmigrate/schema/__init__.py index 9fc12673..6930e414 100644 --- a/rhodecode/lib/dbmigrate/schema/__init__.py +++ b/rhodecode/lib/dbmigrate/schema/__init__.py @@ -22,4 +22,4 @@ def url(*args, **kwargs): Dummy url generator to be used inside the old db migration schemas that rely on it. It would protect from errors after removal of pylons. """ - return '/' + return "/" diff --git a/rhodecode/lib/dbmigrate/schema/db_1_1_0.py b/rhodecode/lib/dbmigrate/schema/db_1_1_0.py index 69643acc..e5d25827 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_1_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_1_0.py @@ -22,19 +22,18 @@ from sqlalchemy.orm import relation, backref, class_mapper from sqlalchemy.orm.session import Session from rhodecode.model.meta import Base -class BaseModel(object): - """Base Model for all classess - """ +class BaseModel(object): + """Base Model for all classess""" @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): @@ -43,11 +42,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -78,32 +82,39 @@ class BaseModel(object): class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' - __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id') - , {'useexisting':True}) + __tablename__ = "user_followings" + __table_args__ = ( + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"useexisting": True}, + ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey(u'users.user_id'), nullable=True, unique=None, default=None) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) - user = relation('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relation("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relation('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relation('Repository') + follows_user = relation("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relation("Repository") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' - __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True}) + __tablename__ = "cache_invalidation" + __table_args__ = (UniqueConstraint("cache_key"), {"useexisting": True}) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(None), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(None), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False diff --git a/rhodecode/lib/dbmigrate/schema/db_1_2_0.py b/rhodecode/lib/dbmigrate/schema/db_1_2_0.py index 4fe5dc56..f2fc110f 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_2_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_2_0.py @@ -42,9 +42,10 @@ from rhodecode.lib.caching_query import FromCache log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== + class ModelSerializer(json.JSONEncoder): """ @@ -70,25 +71,23 @@ class ModelSerializer(json.JSONEncoder): """ def default(self, obj): - - if hasattr(obj, '__json__'): + if hasattr(obj, "__json__"): return obj.__json__() else: return json.JSONEncoder.default(self, obj) -class BaseModel(object): - """Base Model for all classess - """ +class BaseModel(object): + """Base Model for all classess""" @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): @@ -97,11 +96,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -132,18 +136,17 @@ class BaseModel(object): class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = (UniqueConstraint('app_settings_name'), {'extend_existing':True}) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), {"extend_existing": True}) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) - def __init__(self, k='', v=''): + def __init__(self, k="", v=""): self.app_settings_name = k self.app_settings_value = v - - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -151,7 +154,7 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if v == 'ldap_active': + if v == "ldap_active": v = str2bool(v) return v @@ -165,50 +168,44 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __repr__(self): - return "<%s('%s:%s')>" % (self.__class__.__name__, - self.app_settings_name, self.app_settings_value) - + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) @classmethod def get_by_name(cls, ldap_key): - return cls.query()\ - .filter(cls.app_settings_name == ldap_key).scalar() + return cls.query().filter(cls.app_settings_name == ldap_key).scalar() @classmethod def get_app_settings(cls, cache=False): - ret = cls.query() if cache: ret = ret.options(FromCache("sql_cache_short", "get_hg_settings")) if not ret: - raise Exception('Could not get application settings !') + raise Exception("Could not get application settings !") settings = {} for each in ret: - settings['rhodecode_' + each.app_settings_name] = \ - each.app_settings_value + settings["rhodecode_" + each.app_settings_name] = each.app_settings_value return settings @classmethod def get_ldap_settings(cls, cache=False): - ret = cls.query()\ - .filter(cls.app_settings_name.startswith('ldap_')).all() + ret = cls.query().filter(cls.app_settings_name.startswith("ldap_")).all() fd = {} for row in ret: - fd.update({row.app_settings_name:row.app_settings_value}) + fd.update({row.app_settings_name: row.app_settings_value}) return fd class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = (UniqueConstraint('ui_key'), {'extend_existing':True}) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), {"extend_existing": True}) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'pretxnchangegroup.push_logger' - HOOK_PULL = 'preoutgoing.pull_logger' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "pretxnchangegroup.push_logger" + HOOK_PULL = "preoutgoing.pull_logger" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -216,31 +213,27 @@ class RhodeCodeUi(Base, BaseModel): ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - @classmethod def get_by_key(cls, key): return cls.query().filter(cls.ui_key == key) - @classmethod def get_builtin_hooks(cls): q = cls.query() - q = q.filter(cls.ui_key.in_([cls.HOOK_REPO_SIZE, - cls.HOOK_PUSH, cls.HOOK_PULL])) + q = q.filter(cls.ui_key.in_([cls.HOOK_REPO_SIZE, cls.HOOK_PUSH, cls.HOOK_PULL])) return q.all() @classmethod def get_custom_hooks(cls): q = cls.query() - q = q.filter(~cls.ui_key.in_([cls.HOOK_REPO_SIZE, - cls.HOOK_PUSH, cls.HOOK_PULL])) - q = q.filter(cls.ui_section == 'hooks') + q = q.filter(~cls.ui_key.in_([cls.HOOK_REPO_SIZE, cls.HOOK_PUSH, cls.HOOK_PULL])) + q = q.filter(cls.ui_section == "hooks") return q.all() @classmethod def create_or_update_hook(cls, key, val): new_ui = cls.get_by_key(key).scalar() or cls() - new_ui.ui_section = 'hooks' + new_ui.ui_section = "hooks" new_ui.ui_active = True new_ui.ui_key = key new_ui.ui_value = val @@ -250,8 +243,8 @@ class RhodeCodeUi(Base, BaseModel): class User(Base, BaseModel): - __tablename__ = 'users' - __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'extend_existing':True}) + __tablename__ = "users" + __table_args__ = (UniqueConstraint("username"), UniqueConstraint("email"), {"extend_existing": True}) user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) password = Column("password", String(255), nullable=True, unique=None, default=None) @@ -264,22 +257,24 @@ class User(Base, BaseModel): ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - user_log = relationship('UserLog', cascade='all') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog", cascade="all") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") @property def full_contact(self): - return '%s %s <%s>' % (self.name, self.lastname, self.email) + return "%s %s <%s>" % (self.name, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.name, self.lastname) + return "%s %s" % (self.name, self.lastname) @property def is_admin(self): @@ -287,8 +282,7 @@ class User(Base, BaseModel): def __repr__(self): try: - return "<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) except: return self.__class__.__name__ @@ -309,7 +303,7 @@ class User(Base, BaseModel): self.last_login = datetime.datetime.now() Session.add(self) Session.commit() - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) @classmethod def create(cls, form_data): @@ -318,11 +312,11 @@ class User(Base, BaseModel): try: new_user = cls() for k, v in form_data.items(): - if k == 'password': + if k == "password": v = get_crypt_password(v) setattr(new_user, k, v) - new_user.api_key = generate_auth_token(form_data['username']) + new_user.api_key = generate_auth_token(form_data["username"]) Session.add(new_user) Session.commit() return new_user @@ -331,12 +325,15 @@ class User(Base, BaseModel): Session.rollback() raise + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = {'extend_existing':True} + __tablename__ = "user_logs" + __table_args__ = {"extend_existing": True} user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) @@ -346,42 +343,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository') + user = relationship("User") + repository = relationship("Repository") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = {'extend_existing':True} + __tablename__ = "users_groups" + __table_args__ = {"extend_existing": True} users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") def __repr__(self): - return '' % (self.users_group_name) + return "" % (self.users_group_name) @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.users_group_name.ilike(group_name)) + gr = cls.query().filter(cls.users_group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.users_group_name == group_name) + gr = cls.query().filter(cls.users_group_name == group_name) if cache: - gr = gr.options(FromCache("sql_cache_short", - "get_user_%s" % group_name)) + gr = gr.options(FromCache("sql_cache_short", "get_user_%s" % group_name)) return gr.scalar() @classmethod def get(cls, users_group_id, cache=False): users_group = cls.query() if cache: - users_group = users_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % users_group_id)) + users_group = users_group.options(FromCache("sql_cache_short", "get_users_group_%s" % users_group_id)) return users_group.get(users_group_id) @classmethod @@ -401,12 +394,11 @@ class UserGroup(Base, BaseModel): @classmethod def update(cls, users_group_id, form_data): - try: users_group = cls.get(users_group_id, cache=False) for k, v in form_data.items(): - if k == 'users_group_members': + if k == "users_group_members": users_group.members = [] Session.flush() members_list = [] @@ -415,7 +407,7 @@ class UserGroup(Base, BaseModel): for u_id in set(v): member = UserGroupMember(users_group_id, u_id) members_list.append(member) - setattr(users_group, 'members', members_list) + setattr(users_group, "members", members_list) setattr(users_group, k, v) Session.add(users_group) @@ -428,15 +420,13 @@ class UserGroup(Base, BaseModel): @classmethod def delete(cls, user_group_id): try: - # check if this group is not assigned to repo - assigned_groups = UserGroupRepoToPerm.query()\ - .filter(UserGroupRepoToPerm.users_group_id == - user_group_id).all() + assigned_groups = ( + UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.users_group_id == user_group_id).all() + ) if assigned_groups: - raise UserGroupAssignedException( - 'UserGroup assigned to %s' % assigned_groups) + raise UserGroupAssignedException("UserGroup assigned to %s" % assigned_groups) users_group = cls.get(user_group_id, cache=False) Session.delete(users_group) @@ -446,18 +436,28 @@ class UserGroup(Base, BaseModel): Session.rollback() raise + class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = {'extend_existing':True} + __tablename__ = "users_groups_members" + __table_args__ = {"extend_existing": True} - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id @@ -470,50 +470,60 @@ class UserGroupMember(Base, BaseModel): Session.commit() return ugm + class Repository(Base, BaseModel): - __tablename__ = 'repositories' - __table_args__ = (UniqueConstraint('repo_name'), {'extend_existing':True},) + __tablename__ = "repositories" + __table_args__ = ( + UniqueConstraint("repo_name"), + {"extend_existing": True}, + ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) - repo_type = Column("repo_type", String(255), nullable=False, unique=False, default='hg') - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default="hg") + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) - followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') - - logs = relationship('UserLog', cascade='all') + logs = relationship("UserLog", cascade="all") def __repr__(self): - return "<%s('%s:%s')>" % (self.__class__.__name__, - self.repo_id, self.repo_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, self.repo_name) @classmethod def url_sep(cls): - return '/' + return "/" @classmethod def get_by_repo_name(cls, repo_name): q = Session.query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ - .options(joinedload(Repository.group)) + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) + .options(joinedload(Repository.group)) + ) return q.one() @classmethod @@ -527,8 +537,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == - cls.url_sep()) + q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.url_sep()) q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -545,7 +554,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -563,8 +572,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == - Repository.url_sep()) + q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == Repository.url_sep()) q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -592,6 +600,7 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False) @classmethod @@ -606,17 +615,16 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) - - #========================================================================== + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, rev): return get_commit_safe(self.scm_instance, rev) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -626,9 +634,9 @@ class Repository(Base, BaseModel): def last_change(self): return self.scm_instance.last_change - #========================================================================== + # ========================================================================== # SCM CACHE INSTANCE - #========================================================================== + # ========================================================================== @property def invalidate(self): @@ -649,24 +657,23 @@ class Repository(Base, BaseModel): return self.__get_instance() def __get_instance(self): - repo_full_path = self.repo_full_path try: alias = get_scm(repo_full_path)[0] - log.debug('Creating instance of %s repository', alias) + log.debug("Creating instance of %s repository", alias) backend = get_backend(alias) except VCSError: log.error(traceback.format_exc()) - log.error('Perhaps this repository is in db and not in ' - 'filesystem run rescan repositories with ' - '"destroy old data " option from admin panel') + log.error( + "Perhaps this repository is in db and not in " + "filesystem run rescan repositories with " + '"destroy old data " option from admin panel' + ) return - if alias == 'hg': - - repo = backend(safe_str(repo_full_path), create=False, - config=self._config) + if alias == "hg": + repo = backend(safe_str(repo_full_path), create=False, config=self._config) else: repo = backend(repo_full_path, create=False) @@ -675,41 +682,41 @@ class Repository(Base, BaseModel): class Group(Base, BaseModel): - __tablename__ = 'groups' - __table_args__ = (UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing':True},) - __mapper_args__ = {'order_by':'group_name'} + __tablename__ = "groups" + __table_args__ = ( + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True}, + ) + __mapper_args__ = {"order_by": "group_name"} group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) - parent_group = relationship('Group', remote_side=group_id) + parent_group = relationship("Group", remote_side=group_id) - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __repr__(self): - return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): - return '/' + return "/" @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache("sql_cache_short", - "get_group_%s" % group_name)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % group_name)) return gr.scalar() @property @@ -723,14 +730,13 @@ class Group(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('group nested more than %s', - parents_recursion_limit) + log.error("group nested more than %s", parents_recursion_limit) break groups.insert(0, gr) @@ -769,67 +775,71 @@ class Group(Base, BaseModel): return cnt + children_count(self) - def get_new_name(self, group_name): """ returns new full group name based on parent and new name :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return Group.url_sep().join(path_prefix + [group_name]) class Permission(Base, BaseModel): - __tablename__ = 'permissions' - __table_args__ = {'extend_existing':True} + __tablename__ = "permissions" + __table_args__ = {"extend_existing": True} permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) permission_name = Column("permission_name", String(255), nullable=True, unique=None, default=None) permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __repr__(self): - return "<%s('%s:%s')>" % (self.__class__.__name__, - self.permission_id, self.permission_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): return cls.query().filter(cls.permission_name == key).scalar() -class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'extend_existing':True}) - repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - user = relationship('User') - permission = relationship('Permission') - repository = relationship('Repository') +class UserRepoToPerm(Base, BaseModel): + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id"), {"extend_existing": True}) + repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) + + user = relationship("User") + permission = relationship("Permission") + repository = relationship("Repository") + class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'extend_existing':True}) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), {"extend_existing": True}) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission') + user = relationship("User") + permission = relationship("Permission") @classmethod def has_perm(cls, user_id, perm): if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class') + raise Exception("perm needs to be an instance of Permission class") - return cls.query().filter(cls.user_id == user_id)\ - .filter(cls.permission == perm).scalar() is not None + return cls.query().filter(cls.user_id == user_id).filter(cls.permission == perm).scalar() is not None @classmethod def grant_perm(cls, user_id, perm): if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class') + raise Exception("perm needs to be an instance of Permission class") new = cls() new.user_id = user_id @@ -840,59 +850,81 @@ class UserToPerm(Base, BaseModel): except: Session.rollback() - @classmethod def revoke_perm(cls, user_id, perm): if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class') + raise Exception("perm needs to be an instance of Permission class") try: - cls.query().filter(cls.user_id == user_id) \ - .filter(cls.permission == perm).delete() + cls.query().filter(cls.user_id == user_id).filter(cls.permission == perm).delete() Session.commit() except: Session.rollback() -class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = (UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), {'extend_existing':True}) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') +class UserGroupRepoToPerm(Base, BaseModel): + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), {"extend_existing": True}) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) + + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __repr__(self): - return ' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) + class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' - __table_args__ = {'extend_existing':True} - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') + __tablename__ = "users_group_to_perm" + __table_args__ = {"extend_existing": True} + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + users_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def has_perm(cls, users_group_id, perm): if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class') + raise Exception("perm needs to be an instance of Permission class") - return cls.query().filter(cls.users_group_id == - users_group_id)\ - .filter(cls.permission == perm)\ - .scalar() is not None + return ( + cls.query().filter(cls.users_group_id == users_group_id).filter(cls.permission == perm).scalar() is not None + ) @classmethod def grant_perm(cls, users_group_id, perm): if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class') + raise Exception("perm needs to be an instance of Permission class") new = cls() new.users_group_id = users_group_id @@ -903,84 +935,98 @@ class UserGroupToPerm(Base, BaseModel): except: Session.rollback() - @classmethod def revoke_perm(cls, users_group_id, perm): if not isinstance(perm, Permission): - raise Exception('perm needs to be an instance of Permission class') + raise Exception("perm needs to be an instance of Permission class") try: - cls.query().filter(cls.users_group_id == users_group_id) \ - .filter(cls.permission == perm).delete() + cls.query().filter(cls.users_group_id == users_group_id).filter(cls.permission == perm).delete() Session.commit() except: Session.rollback() class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'group_to_perm' - __table_args__ = (UniqueConstraint('group_id', 'permission_id'), {'extend_existing':True}) + __tablename__ = "group_to_perm" + __table_args__ = (UniqueConstraint("group_id", "permission_id"), {"extend_existing": True}) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + + user = relationship("User") + permission = relationship("Permission") + group = relationship("RepoGroup") - user = relationship('User') - permission = relationship('Permission') - group = relationship('RepoGroup') class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = (UniqueConstraint('repository_id'), {'extend_existing':True}) + __tablename__ = "statistics" + __table_args__ = (UniqueConstraint("repository_id"), {"extend_existing": True}) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data + + repository = relationship("Repository", single_parent=True) - repository = relationship('Repository', single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' - __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id') - , {'extend_existing':True}) + __tablename__ = "user_followings" + __table_args__ = ( + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True}, + ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') - - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): return cls.query().filter(cls.follows_repo_id == repo_id) + class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' - __table_args__ = (UniqueConstraint('cache_key'), {'extend_existing':True}) + __tablename__ = "cache_invalidation" + __table_args__ = (UniqueConstraint("cache_key"), {"extend_existing": True}) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __repr__(self): - return "<%s('%s:%s')>" % (self.__class__.__name__, - self.cache_id, self.cache_key) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.cache_id, self.cache_key) @classmethod def invalidate(cls, key): @@ -991,10 +1037,12 @@ class CacheInvalidation(Base, BaseModel): :param key: """ - return cls.query()\ - .filter(CacheInvalidation.cache_key == key)\ - .filter(CacheInvalidation.cache_active == False)\ - .scalar() + return ( + cls.query() + .filter(CacheInvalidation.cache_key == key) + .filter(CacheInvalidation.cache_active == False) + .scalar() + ) @classmethod def set_invalidate(cls, key): @@ -1004,13 +1052,12 @@ class CacheInvalidation(Base, BaseModel): :param key: """ - log.debug('marking %s for invalidation', key) - inv_obj = Session.query(cls)\ - .filter(cls.cache_key == key).scalar() + log.debug("marking %s for invalidation", key) + inv_obj = Session.query(cls).filter(cls.cache_key == key).scalar() if inv_obj: inv_obj.cache_active = False else: - log.debug('cache key not found in invalidation db -> creating one') + log.debug("cache key not found in invalidation db -> creating one") inv_obj = CacheInvalidation(key) try: @@ -1027,15 +1074,15 @@ class CacheInvalidation(Base, BaseModel): :param key: """ - inv_obj = Session.query(CacheInvalidation)\ - .filter(CacheInvalidation.cache_key == key).scalar() + inv_obj = Session.query(CacheInvalidation).filter(CacheInvalidation.cache_key == key).scalar() inv_obj.cache_active = True Session.add(inv_obj) Session.commit() + class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = {'extend_existing':True} - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + __tablename__ = "db_migrate_version" + __table_args__ = {"extend_existing": True} + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_1_3_0.py b/rhodecode/lib/dbmigrate/schema/db_1_3_0.py index 1dd53f3f..190efd2e 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_3_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_3_0.py @@ -42,9 +42,9 @@ import hashlib log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -73,8 +73,7 @@ class ModelSerializer(json.JSONEncoder): """ def default(self, obj): - - if hasattr(obj, '__json__'): + if hasattr(obj, "__json__"): return obj.__json__() else: return json.JSONEncoder.default(self, obj) @@ -87,30 +86,35 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - for k, val in getattr(self, '__json__', lambda: {})().items(): + for k, val in getattr(self, "__json__", lambda: {})().items(): d[k] = val return d def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -139,28 +143,27 @@ class BaseModel(object): Session.delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) - def __init__(self, k='', v=''): + def __init__(self, k="", v=""): self.app_settings_name = k self.app_settings_value = v - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -168,7 +171,7 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if self.app_settings_name == 'ldap_active': + if self.app_settings_name == "ldap_active": v = str2bool(v) return v @@ -182,55 +185,47 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, - self.app_settings_name, self.app_settings_value - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) @classmethod def get_by_name(cls, ldap_key): - return cls.query()\ - .filter(cls.app_settings_name == ldap_key).scalar() + return cls.query().filter(cls.app_settings_name == ldap_key).scalar() @classmethod def get_app_settings(cls, cache=False): - ret = cls.query() if cache: ret = ret.options(FromCache("sql_cache_short", "get_hg_settings")) if not ret: - raise Exception('Could not get application settings !') + raise Exception("Could not get application settings !") settings = {} for each in ret: - settings['rhodecode_' + each.app_settings_name] = \ - each.app_settings_value + settings["rhodecode_" + each.app_settings_name] = each.app_settings_value return settings @classmethod def get_ldap_settings(cls, cache=False): - ret = cls.query()\ - .filter(cls.app_settings_name.startswith('ldap_')).all() + ret = cls.query().filter(cls.app_settings_name.startswith("ldap_")).all() fd = {} for row in ret: - fd.update({row.app_settings_name:row.app_settings_value}) + fd.update({row.app_settings_name: row.app_settings_value}) return fd class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'pretxnchangegroup.push_logger' - HOOK_PULL = 'preoutgoing.pull_logger' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "pretxnchangegroup.push_logger" + HOOK_PULL = "preoutgoing.pull_logger" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -245,22 +240,20 @@ class RhodeCodeUi(Base, BaseModel): @classmethod def get_builtin_hooks(cls): q = cls.query() - q = q.filter(cls.ui_key.in_([cls.HOOK_REPO_SIZE, - cls.HOOK_PUSH, cls.HOOK_PULL])) + q = q.filter(cls.ui_key.in_([cls.HOOK_REPO_SIZE, cls.HOOK_PUSH, cls.HOOK_PULL])) return q.all() @classmethod def get_custom_hooks(cls): q = cls.query() - q = q.filter(~cls.ui_key.in_([cls.HOOK_REPO_SIZE, - cls.HOOK_PUSH, cls.HOOK_PULL])) - q = q.filter(cls.ui_section == 'hooks') + q = q.filter(~cls.ui_key.in_([cls.HOOK_REPO_SIZE, cls.HOOK_PUSH, cls.HOOK_PULL])) + q = q.filter(cls.ui_section == "hooks") return q.all() @classmethod def create_or_update_hook(cls, key, val): new_ui = cls.get_by_key(key).scalar() or cls() - new_ui.ui_section = 'hooks' + new_ui.ui_section = "hooks" new_ui.ui_active = True new_ui.ui_key = key new_ui.ui_value = val @@ -269,11 +262,11 @@ class RhodeCodeUi(Base, BaseModel): class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("username"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -287,21 +280,25 @@ class User(Base, BaseModel): ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - user_log = relationship('UserLog', cascade='all') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog", cascade="all") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") @hybrid_property def email(self): @@ -313,28 +310,26 @@ class User(Base, BaseModel): @property def full_name(self): - return '%s %s' % (self.name, self.lastname) + return "%s %s" % (self.name, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.name, self.lastname) - if (self.name and self.lastname) else self.username) + return "%s %s" % (self.name, self.lastname) if (self.name and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.name, self.lastname, self.email) + return "%s %s <%s>" % (self.name, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.name, self.lastname) + return "%s %s" % (self.name, self.lastname) @property def is_admin(self): return self.admin def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @classmethod def get_by_username(cls, username, case_insensitive=False, cache=False): @@ -344,11 +339,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -356,8 +347,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -368,15 +358,14 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % email)) return q.scalar() def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session.add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def __json__(self): return dict( @@ -387,19 +376,16 @@ class User(Base, BaseModel): full_name=self.full_name, full_name_or_username=self.full_name_or_username, short_contact=self.short_contact, - full_contact=self.full_contact + full_contact=self.full_contact, ) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "user_logs" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) @@ -409,118 +395,121 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "users_groups" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") def __unicode__(self): - return u'' % (self.users_group_name) + return "" % (self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, users_group_id, cache=False): users_group = cls.query() if cache: - users_group = users_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % users_group_id)) + users_group = users_group.options(FromCache("sql_cache_short", "get_users_group_%s" % users_group_id)) return users_group.get(users_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, + __tablename__ = "users_groups_members" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) - repo_type = Column("repo_type", String(255), nullable=False, unique=False, default='hg') - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default="hg") + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) - logs = relationship('UserLog') + logs = relationship("UserLog") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__,self.repo_id, - self.repo_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, self.repo_name) @classmethod def url_sep(cls): - return '/' + return "/" @classmethod def get_by_repo_name(cls, repo_name): q = Session.query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ - .options(joinedload(Repository.group)) + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) + .options(joinedload(Repository.group)) + ) return q.scalar() @classmethod @@ -534,8 +523,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session.query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.url_sep()) + q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.url_sep()) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -552,7 +540,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -570,8 +558,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == - Repository.url_sep()) + q = Session.query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == Repository.url_sep()) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -599,6 +586,7 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False) @classmethod @@ -613,16 +601,16 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) - #========================================================================== + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, rev): return get_commit_safe(self.scm_instance, rev) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -638,8 +626,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = defaultdict(list) @@ -647,9 +634,9 @@ class Repository(Base, BaseModel): grouped[cmt.revision].append(cmt) return grouped - #========================================================================== + # ========================================================================== # SCM CACHE INSTANCE - #========================================================================== + # ========================================================================== @property def invalidate(self): @@ -673,19 +660,19 @@ class Repository(Base, BaseModel): repo_full_path = self.repo_full_path try: alias = get_scm(repo_full_path)[0] - log.debug('Creating instance of %s repository', alias) + log.debug("Creating instance of %s repository", alias) backend = get_backend(alias) except VCSError: log.error(traceback.format_exc()) - log.error('Perhaps this repository is in db and not in ' - 'filesystem run rescan repositories with ' - '"destroy old data " option from admin panel') + log.error( + "Perhaps this repository is in db and not in " + "filesystem run rescan repositories with " + '"destroy old data " option from admin panel' + ) return - if alias == 'hg': - - repo = backend(safe_str(repo_full_path), create=False, - config=self._config) + if alias == "hg": + repo = backend(safe_str(repo_full_path), create=False, config=self._config) else: repo = backend(repo_full_path, create=False) @@ -693,50 +680,45 @@ class Repository(Base, BaseModel): class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") - parent_group = relationship('RepoGroup', remote_side=group_id) + parent_group = relationship("RepoGroup", remote_side=group_id) - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): - return '/' + return "/" @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @property @@ -750,13 +732,13 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('group nested more than %s', parents_recursion_limit) + log.error("group nested more than %s", parents_recursion_limit) break groups.insert(0, gr) @@ -780,9 +762,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -803,25 +783,19 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) class Permission(Base, BaseModel): - __tablename__ = 'permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "permissions" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) permission_name = Column("permission_name", String(255), nullable=True, unique=None, default=None) permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -829,38 +803,45 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, default_user_id): - q = Session.query(UserRepoToPerm, Repository, cls)\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ - .join((cls, UserRepoToPerm.permission_id == cls.permission_id))\ - .filter(UserRepoToPerm.user_id == default_user_id) + q = ( + Session.query(UserRepoToPerm, Repository, cls) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) + .join((cls, UserRepoToPerm.permission_id == cls.permission_id)) + .filter(UserRepoToPerm.user_id == default_user_id) + ) return q.all() @classmethod def get_default_group_perms(cls, default_user_id): - q = Session.query(UserRepoGroupToPerm, RepoGroup, cls)\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ - .join((cls, UserRepoGroupToPerm.permission_id == cls.permission_id))\ - .filter(UserRepoGroupToPerm.user_id == default_user_id) + q = ( + Session.query(UserRepoGroupToPerm, RepoGroup, cls) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) + .join((cls, UserRepoGroupToPerm.permission_id == cls.permission_id)) + .filter(UserRepoGroupToPerm.user_id == default_user_id) + ) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -872,39 +853,52 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.user, self.repository) + return " %s >" % (self.user, self.repository) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -916,96 +910,130 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -1013,25 +1041,23 @@ class UserFollowing(Base, BaseModel): class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, - self.cache_id, self.cache_key) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.cache_id, self.cache_key) @classmethod def _get_key(cls, key): @@ -1041,11 +1067,12 @@ class CacheInvalidation(Base, BaseModel): :param key: """ import rhodecode - prefix = '' - iid = rhodecode.CONFIG.get('instance_id') + + prefix = "" + iid = rhodecode.CONFIG.get("instance_id") if iid: prefix = iid - return "%s%s" % (prefix, key), prefix, key.rstrip('_README') + return "%s%s" % (prefix, key), prefix, key.rstrip("_README") @classmethod def get_by_key(cls, key): @@ -1090,7 +1117,7 @@ class CacheInvalidation(Base, BaseModel): key, _prefix, _org_key = cls._get_key(key) inv_objs = Session.query(cls).filter(cls.cache_args == _org_key).all() - log.debug('marking %s key[s] %s for invalidation', len(inv_objs), _org_key) + log.debug("marking %s key[s] %s for invalidation", len(inv_objs), _org_key) try: for inv_obj in inv_objs: if inv_obj: @@ -1116,22 +1143,19 @@ class CacheInvalidation(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, - ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=False) - line_no = Column('line_no', Unicode(10), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) + __tablename__ = "changeset_comments" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=False) + line_no = Column("line_no", Unicode(10), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') + author = relationship("User", lazy="joined") + repo = relationship("Repository") @classmethod def get_users(cls, revision): @@ -1142,38 +1166,31 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - return Session.query(User)\ - .filter(cls.revision == revision)\ - .join(ChangesetComment.author).all() + return Session.query(User).filter(cls.revision == revision).join(ChangesetComment.author).all() class Notification(Base, BaseModel): - __tablename__ = 'notifications' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "notifications" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self).all()] + return [x.user for x in UserNotification.query().filter(UserNotification.notification == self).all()] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -1197,24 +1214,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -1222,39 +1244,34 @@ class UserNotification(Base, BaseModel): class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine':'InnoDB', - 'mysql_charset': 'utf8'}, - ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + __tablename__ = "db_migrate_version" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) + ## this is migration from 1_4_0, but now it's here to overcome a problem of ## attaching a FK to this from 1_3_0 ! class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_requests" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) # 500 revisions max - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) # 500 revisions max + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_1_4_0.py b/rhodecode/lib/dbmigrate/schema/db_1_4_0.py index f0b59eb6..8cdf2513 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_4_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_4_0.py @@ -44,12 +44,12 @@ from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -61,20 +61,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -85,11 +85,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -130,28 +135,27 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) - def __init__(self, k='', v=''): + def __init__(self, k="", v=""): self.app_settings_name = k self.app_settings_value = v - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -159,7 +163,7 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if self.app_settings_name == 'ldap_active': + if self.app_settings_name == "ldap_active": v = str2bool(v) return v @@ -173,25 +177,21 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, - self.app_settings_name, self.app_settings_value - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -200,20 +200,22 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" DEFAULT_PERMISSIONS = [ - 'hg.register.manual_activate', 'hg.create.repository', - 'hg.fork.repository', 'repository.read', 'group.read' + "hg.register.manual_activate", + "hg.create.repository", + "hg.fork.repository", + "repository.read", + "group.read", ] user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -226,24 +228,30 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - user_log = relationship('UserLog', cascade='all') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog", cascade="all") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -260,19 +268,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -286,11 +294,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -298,8 +302,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -310,8 +313,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -323,34 +325,31 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -363,175 +362,176 @@ class UserEmailMap(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "user_logs" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) - - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "users_groups" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") def __unicode__(self): - return u'' % (self.users_group_name) + return "" % (self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, users_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % users_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % users_group_id)) return user_group.get(users_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + __tablename__ = "users_groups_members" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - self.repo_name) - + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, self.repo_name) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -540,67 +540,53 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) PERMS = [ - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repositories Group no access')), - ('group.read', _('Repositories Group read access')), - ('group.write', _('Repositories Group write access')), - ('group.admin', _('Repositories Group admin access')), - - ('hg.admin', _('RhodeCode Administrator')), - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - ('hg.register.none', _('Register disabled')), - ('hg.register.manual_activate', _('Register new user with RhodeCode ' - 'with manual activation')), - - ('hg.register.auto_activate', _('Register new user with RhodeCode ' - 'with auto activation')), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repositories Group no access")), + ("group.read", _("Repositories Group read access")), + ("group.write", _("Repositories Group write access")), + ("group.admin", _("Repositories Group admin access")), + ("hg.admin", _("RhodeCode Administrator")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Register disabled")), + ("hg.register.manual_activate", _("Register new user with RhodeCode with manual activation")), + ("hg.register.auto_activate", _("Register new user with RhodeCode with auto activation")), ] # defines which permissions are more important higher the more important PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository':1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -608,9 +594,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -618,191 +602,239 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.user, self.repository) + return " %s >" % (self.user, self.repository) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -813,8 +845,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -823,18 +854,17 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -843,126 +873,116 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_requests" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + __tablename__ = "db_migrate_version" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_1_5_0.py b/rhodecode/lib/dbmigrate/schema/db_1_5_0.py index 85429ad6..5979de7d 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_5_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_5_0.py @@ -45,12 +45,12 @@ from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -62,20 +62,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -86,11 +86,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -136,28 +141,27 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) - def __init__(self, k='', v=''): + def __init__(self, k="", v=""): self.app_settings_name = k self.app_settings_value = v - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -165,11 +169,13 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if self.app_settings_name in ["ldap_active", - "default_repo_enable_statistics", - "default_repo_enable_locking", - "default_repo_private", - "default_repo_enable_downloads"]: + if self.app_settings_name in [ + "ldap_active", + "default_repo_enable_statistics", + "default_repo_enable_locking", + "default_repo_private", + "default_repo_enable_downloads", + ]: v = str2bool(v) return v @@ -183,25 +189,21 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, - self.app_settings_name, self.app_settings_value - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -210,20 +212,22 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" DEFAULT_PERMISSIONS = [ - 'hg.register.manual_activate', 'hg.create.repository', - 'hg.fork.repository', 'repository.read', 'group.read' + "hg.register.manual_activate", + "hg.create.repository", + "hg.fork.repository", + "repository.read", + "group.read", ] user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -236,26 +240,32 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -272,19 +282,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -298,11 +308,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -310,8 +316,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -322,8 +327,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -335,34 +339,31 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -375,176 +376,177 @@ class UserEmailMap(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "user_logs" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) - - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "users_groups" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") def __unicode__(self): - return u'' % (self.users_group_name) + return "" % (self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, users_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % users_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % users_group_id)) return user_group.get(users_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + __tablename__ = "users_groups_members" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - self.repo_name) - + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, self.repo_name) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -553,75 +555,61 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) PERMS = [ - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repositories Group no access')), - ('group.read', _('Repositories Group read access')), - ('group.write', _('Repositories Group write access')), - ('group.admin', _('Repositories Group admin access')), - - ('hg.admin', _('RhodeCode Administrator')), - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - ('hg.register.none', _('Register disabled')), - ('hg.register.manual_activate', _('Register new user with RhodeCode ' - 'with manual activation')), - - ('hg.register.auto_activate', _('Register new user with RhodeCode ' - 'with auto activation')), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repositories Group no access")), + ("group.read", _("Repositories Group read access")), + ("group.write", _("Repositories Group write access")), + ("group.admin", _("Repositories Group admin access")), + ("hg.admin", _("RhodeCode Administrator")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Register disabled")), + ("hg.register.manual_activate", _("Register new user with RhodeCode with manual activation")), + ("hg.register.auto_activate", _("Register new user with RhodeCode with auto activation")), ] # defines which permissions are more important higher the more important PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository':1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'hg.create.repository', - 'hg.fork.repository', - 'hg.register.manual_activate', + "repository.read", + "group.read", + "hg.create.repository", + "hg.fork.repository", + "hg.register.manual_activate", ] permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -629,9 +617,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -639,191 +625,239 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.user, self.repository) + return " %s >" % (self.user, self.repository) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -834,8 +868,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -844,18 +877,17 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -864,126 +896,116 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_requests" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + __tablename__ = "db_migrate_version" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_1_5_2.py b/rhodecode/lib/dbmigrate/schema/db_1_5_2.py index 7bccc8ec..ab4eff03 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_5_2.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_5_2.py @@ -45,12 +45,12 @@ from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -62,20 +62,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -86,11 +86,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -136,28 +141,27 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) - def __init__(self, k='', v=''): + def __init__(self, k="", v=""): self.app_settings_name = k self.app_settings_value = v - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -165,11 +169,13 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if self.app_settings_name in ["ldap_active", - "default_repo_enable_statistics", - "default_repo_enable_locking", - "default_repo_private", - "default_repo_enable_downloads"]: + if self.app_settings_name in [ + "ldap_active", + "default_repo_enable_statistics", + "default_repo_enable_locking", + "default_repo_private", + "default_repo_enable_downloads", + ]: v = str2bool(v) return v @@ -183,25 +189,21 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, - self.app_settings_name, self.app_settings_value - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -210,20 +212,22 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" DEFAULT_PERMISSIONS = [ - 'hg.register.manual_activate', 'hg.create.repository', - 'hg.fork.repository', 'repository.read', 'group.read' + "hg.register.manual_activate", + "hg.create.repository", + "hg.fork.repository", + "repository.read", + "group.read", ] user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -236,26 +240,32 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -272,19 +282,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -298,11 +308,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -310,8 +316,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -322,8 +327,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -335,34 +339,31 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -375,193 +376,192 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "user_logs" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) - - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "users_groups" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") def __unicode__(self): - return u'' % (self.users_group_name) + return "" % (self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, users_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % users_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % users_group_id)) return user_group.get(users_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + __tablename__ = "users_groups_members" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) - + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -570,67 +570,53 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) PERMS = [ - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repositories Group no access')), - ('group.read', _('Repositories Group read access')), - ('group.write', _('Repositories Group write access')), - ('group.admin', _('Repositories Group admin access')), - - ('hg.admin', _('RhodeCode Administrator')), - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - ('hg.register.none', _('Register disabled')), - ('hg.register.manual_activate', _('Register new user with RhodeCode ' - 'with manual activation')), - - ('hg.register.auto_activate', _('Register new user with RhodeCode ' - 'with auto activation')), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repositories Group no access")), + ("group.read", _("Repositories Group read access")), + ("group.write", _("Repositories Group write access")), + ("group.admin", _("Repositories Group admin access")), + ("hg.admin", _("RhodeCode Administrator")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Register disabled")), + ("hg.register.manual_activate", _("Register new user with RhodeCode with manual activation")), + ("hg.register.auto_activate", _("Register new user with RhodeCode with auto activation")), ] # defines which permissions are more important higher the more important PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository':1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -638,9 +624,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -648,191 +632,239 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.user, self.repository) + return " %s >" % (self.user, self.repository) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -843,8 +875,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -853,18 +884,17 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -873,126 +903,116 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_requests" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + __tablename__ = "db_migrate_version" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_1_6_0.py b/rhodecode/lib/dbmigrate/schema/db_1_6_0.py index 628e76e2..906e8dde 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_6_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_6_0.py @@ -39,19 +39,18 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_suffix, remove_prefix, time_to_datetime +from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, remove_suffix, remove_prefix, time_to_datetime from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -63,20 +62,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -87,11 +86,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -137,28 +141,27 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) - def __init__(self, k='', v=''): + def __init__(self, k="", v=""): self.app_settings_name = k self.app_settings_value = v - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -166,11 +169,13 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if self.app_settings_name in ["ldap_active", - "default_repo_enable_statistics", - "default_repo_enable_locking", - "default_repo_private", - "default_repo_enable_downloads"]: + if self.app_settings_name in [ + "ldap_active", + "default_repo_enable_statistics", + "default_repo_enable_locking", + "default_repo_private", + "default_repo_enable_downloads", + ]: v = str2bool(v) return v @@ -184,25 +189,21 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, - self.app_settings_name, self.app_settings_value - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -211,20 +212,22 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" DEFAULT_PERMISSIONS = [ - 'hg.register.manual_activate', 'hg.create.repository', - 'hg.fork.repository', 'repository.read', 'group.read' + "hg.register.manual_activate", + "hg.create.repository", + "hg.fork.repository", + "repository.read", + "group.read", ] user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -237,26 +240,32 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -273,19 +282,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -299,11 +308,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -311,8 +316,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -323,8 +327,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -336,34 +339,31 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -376,191 +376,187 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "user_logs" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) - - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "users_groups" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") def __unicode__(self): - return u'' % (self.users_group_name) + return "" % (self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, users_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % users_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % users_group_id)) return user_group.get(users_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + __tablename__ = "users_groups_members" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) - #NOTE for this migration we are required tio have it + # NOTE for this migration we are required tio have it @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -579,12 +575,14 @@ class Repository(Base, BaseModel): @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() - #NOTE this is required for this migration to work + # NOTE this is required for this migration to work def update_commit_cache(self, cs_cache=None): """ Update cache of last changeset for repository, keys should be:: @@ -599,6 +597,7 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: cs_cache = EmptyCommit() # Note: Using always the empty commit here in case we are @@ -609,43 +608,45 @@ class Repository(Base, BaseModel): if isinstance(cs_cache, BaseChangeset): cs_cache = cs_cache.__json__() - if (cs_cache != self.changeset_cache or not self.changeset_cache): + if cs_cache != self.changeset_cache or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping repo:%s already with latest changes', self.repo_name) + log.debug("Skipping repo:%s already with latest changes", self.repo_name) + class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -654,67 +655,53 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) PERMS = [ - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('hg.admin', _('RhodeCode Administrator')), - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - ('hg.register.none', _('Register disabled')), - ('hg.register.manual_activate', _('Register new user with RhodeCode ' - 'with manual activation')), - - ('hg.register.auto_activate', _('Register new user with RhodeCode ' - 'with auto activation')), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("hg.admin", _("RhodeCode Administrator")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Register disabled")), + ("hg.register.manual_activate", _("Register new user with RhodeCode with manual activation")), + ("hg.register.auto_activate", _("Register new user with RhodeCode with auto activation")), ] # defines which permissions are more important higher the more important PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository':1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -722,9 +709,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -732,191 +717,239 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.user, self.repository) + return " %s >" % (self.user, self.repository) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -927,8 +960,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -937,18 +969,17 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -957,126 +988,116 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_requests" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + __tablename__ = "db_migrate_version" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_1_7_0.py b/rhodecode/lib/dbmigrate/schema/db_1_7_0.py index 2510bd87..d41fd3bd 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_7_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_7_0.py @@ -39,19 +39,18 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_suffix, remove_prefix, time_to_datetime +from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, remove_suffix, remove_prefix, time_to_datetime from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -63,20 +62,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -87,11 +86,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -137,28 +141,27 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) - def __init__(self, k='', v=''): + def __init__(self, k="", v=""): self.app_settings_name = k self.app_settings_value = v - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -166,11 +169,13 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if self.app_settings_name in ["ldap_active", - "default_repo_enable_statistics", - "default_repo_enable_locking", - "default_repo_private", - "default_repo_enable_downloads"]: + if self.app_settings_name in [ + "ldap_active", + "default_repo_enable_statistics", + "default_repo_enable_locking", + "default_repo_private", + "default_repo_enable_downloads", + ]: v = str2bool(v) return v @@ -184,25 +189,21 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, - self.app_settings_name, self.app_settings_value - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -211,17 +212,16 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -234,26 +234,32 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -270,19 +276,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -296,11 +302,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -308,8 +310,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -320,8 +321,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -333,9 +333,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -343,40 +342,36 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user - - class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -389,236 +384,235 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "user_logs" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "users_groups" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, users_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % users_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % users_group_id)) return user_group.get(users_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + __tablename__ = "users_groups_members" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -627,105 +621,84 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -733,9 +706,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -743,250 +714,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -995,149 +1034,138 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_requests" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}, - ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + __tablename__ = "db_migrate_version" + __table_args__ = ({"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"},) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_1_8_0.py b/rhodecode/lib/dbmigrate/schema/db_1_8_0.py index 62bc1a2b..24f4ea72 100644 --- a/rhodecode/lib/dbmigrate/schema/db_1_8_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_1_8_0.py @@ -39,19 +39,18 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_suffix, remove_prefix, time_to_datetime +from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, remove_suffix, remove_prefix, time_to_datetime from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -63,20 +62,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -87,11 +86,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -137,30 +141,29 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(255), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -168,11 +171,13 @@ class RhodeCodeSetting(Base, BaseModel): @hybrid_property def app_settings_value(self): v = self._app_settings_value - if self.app_settings_name in ["ldap_active", - "default_repo_enable_statistics", - "default_repo_enable_locking", - "default_repo_private", - "default_repo_enable_downloads"]: + if self.app_settings_name in [ + "ldap_active", + "default_repo_enable_statistics", + "default_repo_enable_locking", + "default_repo_private", + "default_repo_enable_downloads", + ]: v = str2bool(v) return v @@ -186,25 +191,21 @@ class RhodeCodeSetting(Base, BaseModel): self._app_settings_value = safe_str(val) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, - self.app_settings_name, self.app_settings_value - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.app_settings_name, self.app_settings_value) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -213,17 +214,16 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -236,26 +236,32 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -272,19 +278,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -298,11 +304,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -310,8 +312,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -322,8 +323,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -335,9 +335,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -345,40 +344,36 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user - - class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -391,236 +386,241 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -629,105 +629,84 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -735,9 +714,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -745,250 +722,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -997,149 +1042,144 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_0_0.py b/rhodecode/lib/dbmigrate/schema/db_2_0_0.py index c3b45252..01fe9101 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_0_0.py @@ -40,19 +40,27 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -64,20 +72,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -88,11 +96,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -138,37 +151,36 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str return safe_str(self.__unicode__()) - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -177,7 +189,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -196,30 +208,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -228,17 +240,16 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -251,31 +262,37 @@ class User(Base, BaseModel): last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) - #for migration reasons, this is going to be later deleted + # for migration reasons, this is going to be later deleted ldap_dn = Column("ldap_dn", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -292,19 +309,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -318,11 +335,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -330,8 +343,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -342,8 +354,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -355,9 +366,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -365,40 +375,36 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user - - class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -411,239 +417,244 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # don't trigger lazy load for migrations - #members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + # members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -652,105 +663,84 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -758,9 +748,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -768,250 +756,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1020,149 +1076,144 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_0_1.py b/rhodecode/lib/dbmigrate/schema/db_2_0_1.py index f65bd762..bef77080 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_0_1.py @@ -40,19 +40,27 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -64,20 +72,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -88,11 +96,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -138,40 +151,39 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -180,7 +192,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -199,30 +211,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -231,17 +243,16 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -255,27 +266,33 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -292,19 +309,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -318,11 +335,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -330,8 +343,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -342,8 +354,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -355,9 +366,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -365,40 +375,36 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user - - class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -411,240 +417,245 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) landing_rev = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - #TODO: create this field in migrations - #created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + # TODO: create this field in migrations + # created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -653,105 +664,84 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -759,9 +749,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -769,250 +757,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1021,149 +1077,144 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_0_2.py b/rhodecode/lib/dbmigrate/schema/db_2_0_2.py index 53a99272..9dce03c4 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_0_2.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_0_2.py @@ -40,19 +40,27 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -64,20 +72,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -88,11 +96,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -138,40 +151,39 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -180,7 +192,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -199,30 +211,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -231,17 +243,16 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' + DEFAULT_USER = "default" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -255,27 +266,33 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -292,19 +309,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -318,11 +335,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -330,8 +343,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) return q.scalar() @classmethod @@ -342,8 +354,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -355,9 +366,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -365,40 +375,36 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user - - class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -411,257 +417,261 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - #NOTE: marcink, DO NOT REMOVE THOSE + # NOTE: marcink, DO NOT REMOVE THOSE @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -670,105 +680,84 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -776,9 +765,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -786,250 +773,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1038,149 +1093,144 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_1_0.py b/rhodecode/lib/dbmigrate/schema/db_2_1_0.py index e14ea2cf..bbb7589b 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_1_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_1_0.py @@ -40,19 +40,27 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -64,20 +72,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -88,11 +96,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -138,43 +151,42 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -183,7 +195,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -202,30 +214,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -234,18 +246,17 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -259,27 +270,33 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") @hybrid_property def email(self): @@ -296,19 +313,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -322,11 +339,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -334,32 +347,30 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(cls.email.ilike(email)) else: q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -371,9 +382,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -381,58 +391,54 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -445,240 +451,245 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -687,105 +698,84 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -793,9 +783,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -803,250 +791,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1055,149 +1111,144 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_2_0.py b/rhodecode/lib/dbmigrate/schema/db_2_2_0.py index d5d1904c..402762e8 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_2_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_2_0.py @@ -40,20 +40,28 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int, \ - get_clone_url +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -65,20 +73,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -89,11 +97,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -139,43 +152,42 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -184,7 +196,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -203,30 +215,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -235,21 +247,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -263,29 +274,35 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - #_user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + # _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") @hybrid_property def email(self): @@ -302,19 +319,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -328,11 +345,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -340,32 +353,30 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(cls.email.ilike(email)) else: q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -377,9 +388,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -387,59 +397,55 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -452,249 +458,253 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -703,108 +713,93 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -812,9 +807,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -822,250 +815,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1074,150 +1135,145 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_2_3.py b/rhodecode/lib/dbmigrate/schema/db_2_2_3.py index ce972ae6..48291ddb 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_2_3.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_2_3.py @@ -40,20 +40,28 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int, \ - get_clone_url +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -65,20 +73,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -89,11 +97,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -139,43 +152,42 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -184,7 +196,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -203,30 +215,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -235,21 +247,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -263,29 +274,35 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") @hybrid_property def email(self): @@ -302,19 +319,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -328,11 +345,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -340,32 +353,30 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(cls.email.ilike(email)) else: q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -377,9 +388,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -387,59 +397,55 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -452,164 +458,161 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name) - ) - ) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -617,87 +620,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -706,108 +716,93 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name) - ) - ) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -815,9 +810,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -825,250 +818,318 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1077,153 +1138,148 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_3_0_0.py b/rhodecode/lib/dbmigrate/schema/db_2_3_0_0.py index 6a8c77d8..2308adc0 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_3_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_3_0_0.py @@ -40,20 +40,28 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int, \ - get_clone_url +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -65,20 +73,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -89,11 +97,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -139,43 +152,42 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -184,7 +196,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -203,30 +215,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -235,21 +247,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -263,29 +274,35 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") @hybrid_property def email(self): @@ -302,19 +319,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -328,9 +345,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -338,32 +353,30 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(cls.email.ilike(email)) else: q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -375,9 +388,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -385,67 +397,63 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -458,162 +466,161 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -621,87 +628,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -710,106 +724,93 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -817,9 +818,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -827,153 +826,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -986,100 +1048,105 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1088,153 +1155,148 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_3_0_1.py b/rhodecode/lib/dbmigrate/schema/db_2_3_0_1.py index 6c9d5b45..e7b2e5dc 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_3_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_3_0_1.py @@ -40,20 +40,28 @@ from rhodecode.lib.vcs.exceptions import VCSError from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit -from rhodecode.lib.utils2 import str2bool, safe_str, get_commit_safe, \ - remove_prefix, time_to_datetime, aslist, Optional, safe_int, \ - get_clone_url +from rhodecode.lib.utils2 import ( + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: hashlib.md5(safe_str(k)).hexdigest() @@ -65,20 +73,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -89,11 +97,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -139,43 +152,42 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -184,7 +196,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -203,30 +215,30 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PULL = 'preoutgoing.pre_pull' + HOOK_REPO_SIZE = "changegroup.repo_size" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PULL = "preoutgoing.pre_pull" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -235,21 +247,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -263,29 +274,35 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + repositories = relationship("Repository") + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") @hybrid_property def email(self): @@ -302,19 +319,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -328,9 +345,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -338,32 +353,30 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(cls.email.ilike(email)) else: q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -375,9 +388,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -385,67 +397,63 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -458,162 +466,161 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: q = cls.query().filter(cls.users_group_name.ilike(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(256), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -621,87 +628,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -710,108 +724,95 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query()\ - .filter(cls.group_name.ilike(group_name)) + gr = cls.query().filter(cls.group_name.ilike(group_name)) else: - gr = cls.query()\ - .filter(cls.group_name == group_name) + gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -819,9 +820,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -829,153 +828,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -988,101 +1050,106 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheInvalidation(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1091,153 +1158,148 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(256), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(256), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(256), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(256), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(256), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(256), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(256), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(256), nullable=False) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(256)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(256)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_2_3_0_2.py b/rhodecode/lib/dbmigrate/schema/db_2_3_0_2.py index 6e4a3eb4..09aa754f 100644 --- a/rhodecode/lib/dbmigrate/schema/db_2_3_0_2.py +++ b/rhodecode/lib/dbmigrate/schema/db_2_3_0_2.py @@ -44,19 +44,29 @@ from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -68,20 +78,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -92,11 +102,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -142,44 +157,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -188,7 +202,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -207,31 +221,31 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # GIT HOOK_PRE_PULL_GIT = "preupload" @@ -246,21 +260,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -274,36 +287,42 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") @hybrid_property def email(self): @@ -320,19 +339,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -346,9 +365,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -356,24 +373,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -381,8 +397,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -394,9 +409,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -404,68 +418,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -478,170 +488,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -649,87 +657,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -738,107 +753,95 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), ] - #definition of system default permissions for DEFAULT user + # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -846,9 +849,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -856,153 +857,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1014,105 +1078,110 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1121,156 +1190,151 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(255), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(255), nullable=False) def __repr__(self): - return '' % (self.pull_request_id,) + return "" % (self.pull_request_id,) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_0_0_0.py b/rhodecode/lib/dbmigrate/schema/db_3_0_0_0.py index d5b6474f..1979743a 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_0_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_0_0_0.py @@ -46,19 +46,29 @@ from zope.cachedescriptors.property import Lazy as LazyProperty from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -70,20 +80,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -94,11 +104,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -144,44 +159,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -190,7 +204,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -209,31 +223,31 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # GIT HOOK_PRE_PULL_GIT = "preupload" @@ -242,8 +256,8 @@ class RhodeCodeUi(Base, BaseModel): HOOK_PUSH_GIT = "postreceive" # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -252,21 +266,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -280,40 +293,45 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -330,19 +348,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -356,9 +374,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -366,24 +382,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -391,8 +406,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -404,9 +418,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -414,68 +427,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -488,170 +497,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -659,87 +666,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", String(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -748,111 +762,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -860,9 +861,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -870,153 +869,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1028,105 +1090,110 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1135,160 +1202,155 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(255), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column('last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column('last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) def __repr__(self): - return '' % (self.pull_request_id,) + return "" % (self.pull_request_id,) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_0_0_1.py b/rhodecode/lib/dbmigrate/schema/db_3_0_0_1.py index 70827865..7737efef 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_0_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_0_0_1.py @@ -43,23 +43,32 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -78,27 +87,27 @@ class EncryptedValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = String def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$'): + if value.startswith("enc$aes$"): # protect against double encrypting if someone manually starts doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes$') - return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes$") + return "enc$aes$%s" % AESCipher(ENCRYPTION_KEY).encrypt(value) def process_result_value(self, value, dialect): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value @@ -114,20 +123,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -138,11 +147,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -188,44 +202,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -234,7 +247,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -253,38 +266,38 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -293,21 +306,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -321,40 +333,45 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -371,19 +388,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -397,9 +414,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -407,24 +422,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -432,8 +446,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -445,9 +458,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -455,68 +467,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -529,170 +537,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -700,87 +706,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -789,111 +802,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -901,9 +901,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -911,153 +909,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1069,105 +1130,110 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1176,160 +1242,155 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(255), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column('last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column('last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) def __repr__(self): - return '' % (self.pull_request_id,) + return "" % (self.pull_request_id,) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_1_0_0.py b/rhodecode/lib/dbmigrate/schema/db_3_1_0_0.py index 1b1b3f2c..b65af842 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_1_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_1_0_0.py @@ -43,23 +43,32 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -78,27 +87,27 @@ class EncryptedValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = String def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$'): + if value.startswith("enc$aes$"): # protect against double encrypting if someone manually starts doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes$') - return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes$") + return "enc$aes$%s" % AESCipher(ENCRYPTION_KEY).encrypt(value) def process_result_value(self, value, dialect): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value @@ -114,20 +123,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -138,11 +147,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -188,44 +202,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -234,7 +247,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -253,38 +266,38 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -293,21 +306,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -321,40 +333,45 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -371,19 +388,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -397,9 +414,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -407,24 +422,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -432,8 +446,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -445,9 +458,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -455,68 +467,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -529,170 +537,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -700,87 +706,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -789,111 +802,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -901,9 +901,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -911,153 +909,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1069,105 +1130,110 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1176,169 +1242,162 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) class PullRequest(Base, BaseModel): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - pull_request_id = Column('pull_request_id', Integer(), nullable=False, primary_key=True) - title = Column('title', Unicode(255), nullable=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - _revisions = Column('revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) - org_repo_id = Column('org_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) - other_repo_id = Column('other_repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column('last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column('last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) + org_repo_id = Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) + other_repo_id = Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) def __repr__(self): - return '' % (self.pull_request_id,) + return "" % (self.pull_request_id,) - author = relationship('User', lazy='joined') - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - org_repo = relationship('Repository', primaryjoin='PullRequest.org_repo_id==Repository.repo_id') - other_repo = relationship('Repository', primaryjoin='PullRequest.other_repo_id==Repository.repo_id') - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") + author = relationship("User", lazy="joined") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + org_repo = relationship("Repository", primaryjoin="PullRequest.org_repo_id==Repository.repo_id") + other_repo = relationship("Repository", primaryjoin="PullRequest.other_repo_id==Repository.repo_id") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_1_0_1.py b/rhodecode/lib/dbmigrate/schema/db_3_1_0_1.py index e5115669..a41a14be 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_1_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_1_0_1.py @@ -44,23 +44,32 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -79,27 +88,27 @@ class EncryptedValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = String def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$'): + if value.startswith("enc$aes$"): # protect against double encrypting if someone manually starts doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes$') - return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes$") + return "enc$aes$%s" % AESCipher(ENCRYPTION_KEY).encrypt(value) def process_result_value(self, value, dialect): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value @@ -115,20 +124,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -139,11 +148,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -189,44 +203,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -235,7 +248,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -254,38 +267,38 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -294,21 +307,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -322,40 +334,45 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -372,19 +389,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -398,9 +415,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -408,24 +423,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -433,8 +447,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -446,9 +459,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -456,68 +468,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -530,170 +538,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -701,87 +707,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -790,111 +803,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -902,9 +902,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -912,153 +910,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1070,113 +1131,120 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1185,26 +1253,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) class _PullRequestBase(BaseModel): @@ -1212,210 +1277,184 @@ class _PullRequestBase(BaseModel): Common attributes of pull request and version entries. """ - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def org_repo_id(cls): - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def other_repo_id(cls): - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.org_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.org_repo_id==Repository.repo_id" % cls.__name__) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.other_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.other_repo_id==Repository.repo_id" % cls.__name__) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column('pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column('pull_request_id', Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column('pull_requests_reviewers_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_2_0_0.py b/rhodecode/lib/dbmigrate/schema/db_3_2_0_0.py index 82a9c875..a41a14be 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_2_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_2_0_0.py @@ -44,23 +44,32 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -79,27 +88,27 @@ class EncryptedValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = String def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$'): + if value.startswith("enc$aes$"): # protect against double encrypting if someone manually starts doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes$') - return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes$") + return "enc$aes$%s" % AESCipher(ENCRYPTION_KEY).encrypt(value) def process_result_value(self, value, dialect): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value @@ -115,20 +124,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -139,11 +148,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -189,44 +203,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -235,7 +248,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -254,38 +267,38 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -294,21 +307,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -322,40 +334,45 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -372,19 +389,19 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -398,9 +415,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -408,24 +423,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -433,8 +447,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -446,9 +459,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -456,68 +468,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -530,170 +538,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) action = Column("action", String(1200000), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -701,87 +707,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -790,111 +803,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -902,9 +902,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -912,153 +910,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1070,113 +1131,120 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1185,26 +1253,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) class _PullRequestBase(BaseModel): @@ -1212,218 +1277,184 @@ class _PullRequestBase(BaseModel): Common attributes of pull request and version entries. """ - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def org_repo_id(cls): - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def other_repo_id(cls): - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.org_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.org_repo_id==Repository.repo_id" % cls.__name__) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.other_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.other_repo_id==Repository.repo_id" % cls.__name__) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_3_0_0.py b/rhodecode/lib/dbmigrate/schema/db_3_3_0_0.py index bec59f09..be730951 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_3_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_3_0_0.py @@ -33,8 +33,7 @@ from sqlalchemy import * from sqlalchemy.exc import OperationalError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound @@ -45,23 +44,32 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -80,27 +88,27 @@ class EncryptedValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = String def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$'): + if value.startswith("enc$aes$"): # protect against double encrypting if someone manually starts doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes$') - return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes$") + return "enc$aes$%s" % AESCipher(ENCRYPTION_KEY).encrypt(value) def process_result_value(self, value, dialect): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value @@ -116,20 +124,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -140,11 +148,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tupples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -190,44 +203,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -236,7 +248,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -255,38 +267,38 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -295,21 +307,20 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -323,40 +334,45 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -373,24 +389,24 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -404,9 +420,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -414,24 +428,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -439,8 +452,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -452,9 +464,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -462,68 +473,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -536,170 +543,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -707,87 +712,94 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship('UserRepoToPerm', cascade='all', order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) - followers = relationship('UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship('RepositoryField', - cascade="all, delete, delete-orphan") + followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship('ChangesetComment', cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") - pull_requests_org = relationship('PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_org = relationship( + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) - pull_requests_other = relationship('PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + pull_requests_other = relationship( + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -796,111 +808,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -908,9 +907,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -918,153 +915,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1076,117 +1136,124 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1195,26 +1262,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) class _PullRequestBase(BaseModel): @@ -1222,222 +1286,188 @@ class _PullRequestBase(BaseModel): Common attributes of pull request and version entries. """ - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def org_repo_id(cls): - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def other_repo_id(cls): - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.org_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.org_repo_id==Repository.repo_id" % cls.__name__) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.other_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.other_repo_id==Repository.repo_id" % cls.__name__) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_5_0_0.py b/rhodecode/lib/dbmigrate/schema/db_3_5_0_0.py index c58cfeb9..2edb86ad 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_5_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_5_0_0.py @@ -33,8 +33,7 @@ from sqlalchemy import * from sqlalchemy.exc import OperationalError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound @@ -45,23 +44,32 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) @@ -80,27 +88,27 @@ class EncryptedValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = String def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$'): + if value.startswith("enc$aes$"): # protect against double encrypting if someone manually starts doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes$') - return 'enc$aes$%s' % AESCipher(ENCRYPTION_KEY).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes$") + return "enc$aes$%s" % AESCipher(ENCRYPTION_KEY).encrypt(value) def process_result_value(self, value, dialect): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value @@ -116,20 +124,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -140,11 +148,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -190,44 +203,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -236,7 +248,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -255,38 +267,38 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -295,54 +307,40 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) # TODO: Move it to some common place with RhodeCodeSetting SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -351,8 +349,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value type_ = self.app_settings_type - converter = ( - self.SETTINGS_TYPES.get(type_) or self.SETTINGS_TYPES['unicode']) + converter = self.SETTINGS_TYPES.get(type_) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -371,62 +368,58 @@ class RepoRhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -440,40 +433,45 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -490,24 +488,24 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -521,9 +519,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -531,24 +527,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -556,8 +551,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -569,9 +563,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -579,68 +572,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -653,170 +642,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) repo_name = Column("repo_name", String(255), nullable=False, unique=True, default=None) @@ -824,92 +811,93 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_org = relationship( - 'PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) pull_requests_other = relationship( - 'PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -918,111 +906,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -1030,9 +1005,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -1040,153 +1013,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1198,117 +1234,124 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1317,26 +1360,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) class _PullRequestBase(BaseModel): @@ -1344,222 +1384,188 @@ class _PullRequestBase(BaseModel): Common attributes of pull request and version entries. """ - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def org_repo_id(cls): - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def other_repo_id(cls): - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.org_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.org_repo_id==Repository.repo_id" % cls.__name__) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.other_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.other_repo_id==Repository.repo_id" % cls.__name__) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_3_7_0_0.py b/rhodecode/lib/dbmigrate/schema/db_3_7_0_0.py index 0e380d54..c2dda7a5 100644 --- a/rhodecode/lib/dbmigrate/schema/db_3_7_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_3_7_0_0.py @@ -33,8 +33,7 @@ from sqlalchemy import * from sqlalchemy.exc import OperationalError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound @@ -46,38 +45,47 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) -#============================================================================== +# ============================================================================== # BASE CLASSES -#============================================================================== +# ============================================================================== _hash_key = lambda k: md5_safe(k) # this is propagated from .ini file beaker.session.secret # and initialized at environment.py -ENCRYPTION_KEY: bytes = b'' +ENCRYPTION_KEY: bytes = b"" # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -89,8 +97,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -103,6 +111,7 @@ class EncryptedValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = String def process_bind_param(self, value, dialect): @@ -110,17 +119,15 @@ class EncryptedValue(TypeDecorator): Setter for storing value """ import rhodecode + if not value: return value # protect against double encrypting if values is already encrypted - if value.startswith('enc$aes$') \ - or value.startswith('enc$aes_hmac$') \ - or value.startswith('enc2$'): - raise ValueError('value needs to be in unencrypted format, ' - 'ie. not starting with enc$ or enc2$') + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$") or value.startswith("enc2$"): + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$ or enc2$") - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" bytes_val = enc_utils.encrypt_value(value, enc_key=ENCRYPTION_KEY, algo=algo) return safe_str(bytes_val) @@ -130,10 +137,11 @@ class EncryptedValue(TypeDecorator): """ import rhodecode + if not value: return value - enc_strict_mode = rhodecode.ConfigGet().get_bool('rhodecode.encrypted_values.strict', missing=True) + enc_strict_mode = rhodecode.ConfigGet().get_bool("rhodecode.encrypted_values.strict", missing=True) bytes_val = enc_utils.decrypt_value(value, enc_key=ENCRYPTION_KEY, strict_mode=enc_strict_mode) @@ -147,20 +155,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -171,11 +179,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -221,44 +234,43 @@ class BaseModel(object): Session().delete(obj) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -267,7 +279,7 @@ class RhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value _type = self.app_settings_type - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -286,38 +298,38 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) @@ -326,54 +338,40 @@ class RhodeCodeUi(Base, BaseModel): ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) # TODO: Move it to some common place with RhodeCodeSetting SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_value = val self.app_settings_type = type - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -382,8 +380,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_value(self): v = self._app_settings_value type_ = self.app_settings_type - converter = ( - self.SETTINGS_TYPES.get(type_) or self.SETTINGS_TYPES['unicode']) + converter = self.SETTINGS_TYPES.get(type_) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -402,62 +399,58 @@ class RepoRhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): if val not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -471,41 +464,46 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -522,24 +520,24 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -553,9 +551,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.username == username) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_user_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_%s" % _hash_key(username))) return q.scalar() @classmethod @@ -563,24 +559,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -588,8 +583,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -601,9 +595,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -611,68 +604,64 @@ class User(Base, BaseModel): def get_first_admin(cls): user = User.query().filter(User.admin == True).first() if user is None: - raise Exception('Missing administrative account!') + raise Exception("Missing administrative account!") return user @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('Missing default account!') + raise Exception("Missing default account!") return user class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -685,170 +674,168 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - UniqueConstraint('repo_name'), - Index('r_repo_name_idx', 'repo_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repo_name"), + Index("r_repo_name_idx", "repo_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP @@ -858,92 +845,93 @@ class Repository(Base, BaseModel): clone_uri = Column("clone_uri", EncryptedValue(255), nullable=True, unique=False, default=None) repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) _locked = Column("locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) #JSON data + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - fork_id = Column("fork_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=False, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=False, default=None) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User') - fork = relationship('Repository', remote_side=repo_id) - group = relationship('RepoGroup') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User") + fork = relationship("Repository", remote_side=repo_id) + group = relationship("RepoGroup") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_org = relationship( - 'PullRequest', - primaryjoin='PullRequest.org_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", primaryjoin="PullRequest.org_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) pull_requests_other = relationship( - 'PullRequest', - primaryjoin='PullRequest.other_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") + "PullRequest", primaryjoin="PullRequest.other_repo_id==Repository.repo_id", cascade="all, delete, delete-orphan" + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @classmethod def get_by_repo_name(cls, repo_name): q = Session().query(cls).filter(cls.repo_name == repo_name) - q = q.options(joinedload(Repository.fork))\ - .options(joinedload(Repository.user))\ + q = ( + q.options(joinedload(Repository.fork)) + .options(joinedload(Repository.user)) .options(joinedload(Repository.group)) + ) return q.scalar() class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def url_sep(cls): @@ -952,111 +940,98 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -1064,9 +1039,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -1074,153 +1047,216 @@ class Permission(Base, BaseModel): class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -1232,117 +1268,124 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -1351,26 +1394,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) class _PullRequestBase(BaseModel): @@ -1378,222 +1418,188 @@ class _PullRequestBase(BaseModel): Common attributes of pull request and version entries. """ - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def org_repo_id(cls): - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - org_ref = Column('org_ref', Unicode(255), nullable=False) + org_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def other_repo_id(cls): - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - other_ref = Column('other_ref', Unicode(255), nullable=False) - _last_merge_org_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + other_ref = Column("other_ref", Unicode(255), nullable=False) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.org_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.org_repo_id==Repository.repo_id" % cls.__name__) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.other_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.other_repo_id==Repository.repo_id" % cls.__name__) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_11_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_11_0_0.py index 4ed1cf24..63594915 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_11_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_11_0_0.py @@ -33,14 +33,32 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType) + or_, + and_, + not_, + func, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, +) from sqlalchemy.sql.expression import true, false from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -53,18 +71,28 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -79,10 +107,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -94,8 +122,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -106,7 +134,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -130,9 +158,7 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts @@ -146,18 +172,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -165,27 +190,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -196,20 +220,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -220,11 +244,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -281,49 +310,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -333,14 +363,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -352,7 +381,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -363,95 +392,74 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -461,7 +469,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -481,63 +489,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -548,57 +552,63 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -611,6 +621,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -618,6 +629,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -627,11 +639,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -644,10 +658,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -656,10 +672,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] @property @@ -668,23 +681,19 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @property def feed_token(self): return self.get_feed_token() def get_feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -693,25 +702,24 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -719,10 +727,11 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -735,9 +744,11 @@ class User(Base, BaseModel): # token has a scope, we need to verify it if scope_repo_id != token.repo_id: log.debug( - 'Scope mismatch: token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - token.repo, scope_repo_id) + "Scope mismatch: token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + token.repo, + scope_repo_id, + ) # token has a scope, and it doesn't match, skip token continue @@ -765,29 +776,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -798,6 +808,7 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -813,44 +824,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -858,7 +866,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -867,8 +874,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -880,9 +886,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -894,6 +899,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -912,19 +918,19 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" self.last_activity = datetime.datetime.now() Session().add(self) - log.debug('updated user `%s` last activity', self.username) + log.debug("updated user `%s` last activity", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -936,7 +942,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -944,14 +950,13 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -960,14 +965,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -981,98 +987,89 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key', unique=True), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key", unique=True), + Index("uak_api_key_expires_idx", "api_key", "expires"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1080,12 +1077,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1097,11 +1095,11 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -1112,8 +1110,8 @@ class UserApiKeys(Base, BaseModel): if self.repo: return repr(self.repo) if self.repo_group: - return repr(self.repo_group) + ' (recursive)' - return 'global' + return repr(self.repo_group) + " (recursive)" + return "global" @property def scope_humanized(self): @@ -1126,26 +1124,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1158,24 +1154,23 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1185,44 +1180,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1232,41 +1222,48 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1277,35 +1274,40 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1320,6 +1322,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property @@ -1338,22 +1341,17 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1363,15 +1361,16 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1389,7 +1388,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_user_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1413,9 +1412,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1426,11 +1427,12 @@ class UserGroup(Base, BaseModel): perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1441,12 +1443,12 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "owner_email": user_group.user.email, } if with_group_members: @@ -1454,199 +1456,179 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1655,13 +1637,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1707,13 +1690,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1734,8 +1716,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1752,8 +1733,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1795,7 +1775,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1813,8 +1793,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1832,10 +1811,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1852,13 +1828,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1876,7 +1855,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_user_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1899,11 +1878,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1930,32 +1910,30 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2003,7 +1981,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2016,40 +1994,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -2063,45 +2039,44 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: rc_config = SettingsModel().get_all_settings(cache=True) - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI request = get_current_request() - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + request=request, uri_tmpl=uri_tmpl, repo_name=self.repo_name, repo_id=self.repo_id, **override + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2111,8 +2086,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2139,12 +2113,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -2152,28 +2126,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2189,8 +2163,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2204,19 +2177,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2236,8 +2204,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2249,9 +2216,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2264,74 +2231,78 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2342,12 +2313,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2357,14 +2327,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2373,13 +2341,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user).scalar() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2405,14 +2370,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2440,9 +2408,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2491,15 +2457,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2517,7 +2484,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_user_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2541,9 +2508,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2561,115 +2530,104 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2677,9 +2635,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2687,130 +2643,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2822,24 +2757,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2851,42 +2791,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2898,25 +2851,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2928,40 +2897,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2974,21 +2959,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3000,44 +2995,55 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "statistics" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3045,31 +3051,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3111,13 +3114,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -3128,19 +3131,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -3152,41 +3151,44 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, backref='resolved_by') - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, backref="resolved_by") + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3197,8 +3199,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3209,7 +3210,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3245,26 +3246,25 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, } return data @@ -3275,18 +3275,17 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3295,26 +3294,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3327,8 +3323,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3344,64 +3340,49 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + target_ref = Column("other_ref", Unicode(255), nullable=False) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -3410,15 +3391,16 @@ class _PullRequestBase(BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -3430,13 +3412,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3444,9 +3424,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3466,7 +3444,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3477,7 +3455,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -3488,97 +3466,82 @@ class _PullRequestBase(BaseModel): if with_merge_state: merge_status = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status[0], - 'message': safe_str(merge_status[1]), + "status": merge_status[0], + "message": safe_str(merge_status[1]), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus', - cascade="all, delete, delete-orphan") - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3589,7 +3552,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3597,35 +3560,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3643,49 +3601,47 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(workspace_id) return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -3707,10 +3663,9 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) @hybrid_property @@ -3723,56 +3678,51 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3802,20 +3752,24 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3823,38 +3777,38 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -3872,6 +3826,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -3882,8 +3837,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3893,54 +3848,49 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3984,31 +3934,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4016,97 +3963,99 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + __tablename__ = "repo_review_rules_users" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_glob(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, branch, files_changed): """ @@ -4116,16 +4065,16 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - branch = branch or '' + branch = branch or "" files_changed = files_changed or [] branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False file_regex = re.compile(glob2re(self.file_pattern)) for filename in files_changed: @@ -4137,7 +4086,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4145,62 +4094,67 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: users[member.user.username] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -4209,8 +4163,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -4231,8 +4184,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -4250,6 +4202,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -4268,7 +4221,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -4288,43 +4241,40 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class DbSession(Base, BaseModel): - __tablename__ = 'db_session' + __tablename__ = "db_session" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_13_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_13_0_0.py index 1ead14d8..42de27ea 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_13_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_13_0_0.py @@ -33,14 +33,32 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType) + or_, + and_, + not_, + func, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, +) from sqlalchemy.sql.expression import true, false from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -53,18 +71,28 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -79,10 +107,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -94,8 +122,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -106,7 +134,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -130,9 +158,7 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts @@ -146,18 +172,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -165,27 +190,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -196,20 +220,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -220,11 +244,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -281,49 +310,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -333,14 +363,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -352,7 +381,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -363,95 +392,74 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -461,7 +469,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -481,63 +489,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -548,57 +552,63 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -611,6 +621,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -618,6 +629,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -627,11 +639,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -644,10 +658,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -656,10 +672,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] @property @@ -668,27 +681,23 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("long_term", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("long_term", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -697,25 +706,24 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -723,10 +731,11 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -739,9 +748,11 @@ class User(Base, BaseModel): # token has a scope, we need to verify it if scope_repo_id != token.repo_id: log.debug( - 'Scope mismatch: token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - token.repo, scope_repo_id) + "Scope mismatch: token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + token.repo, + scope_repo_id, + ) # token has a scope, and it doesn't match, skip token continue @@ -769,29 +780,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -802,6 +812,7 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -817,44 +828,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -862,7 +870,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -871,8 +878,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -884,9 +890,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -898,6 +903,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -916,19 +922,19 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" self.last_activity = datetime.datetime.now() Session().add(self) - log.debug('updated user `%s` last activity', self.username) + log.debug("updated user `%s` last activity", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -940,7 +946,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -948,14 +954,13 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -964,14 +969,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -985,98 +991,89 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key', unique=True), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key", unique=True), + Index("uak_api_key_expires_idx", "api_key", "expires"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1084,12 +1081,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1101,11 +1099,11 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -1116,8 +1114,8 @@ class UserApiKeys(Base, BaseModel): if self.repo: return repr(self.repo) if self.repo_group: - return repr(self.repo_group) + ' (recursive)' - return 'global' + return repr(self.repo_group) + " (recursive)" + return "global" @property def scope_humanized(self): @@ -1130,26 +1128,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1162,24 +1158,23 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1189,44 +1184,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1236,41 +1226,48 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1281,35 +1278,40 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1324,6 +1326,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1344,29 +1347,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1376,15 +1374,16 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1402,7 +1401,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_user_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1426,9 +1425,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1439,11 +1440,12 @@ class UserGroup(Base, BaseModel): perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1454,13 +1456,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1468,205 +1470,183 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1675,13 +1655,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1727,13 +1708,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1765,14 +1745,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1814,7 +1792,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1832,8 +1810,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1851,10 +1828,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -1863,16 +1837,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -1895,13 +1865,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1920,7 +1893,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_user_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1945,11 +1918,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1976,33 +1950,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2050,7 +2022,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2063,40 +2035,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -2110,9 +2080,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2120,54 +2091,52 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides if not uri_tmpl: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI request = get_current_request() - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + request=request, uri_tmpl=uri_tmpl, repo_name=self.repo_name, repo_id=self.repo_id, **override + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2177,8 +2146,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2205,12 +2173,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -2218,28 +2186,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2255,8 +2223,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2270,19 +2237,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2302,8 +2264,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2315,9 +2276,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2330,74 +2291,78 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2408,12 +2373,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2423,14 +2387,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2439,13 +2401,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user).scalar() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2471,14 +2430,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2506,9 +2468,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2557,15 +2517,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2583,7 +2544,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_user_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2607,9 +2568,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2627,130 +2590,117 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch - 'branch.push', + "branch.push", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2758,9 +2708,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2768,132 +2716,111 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -2905,24 +2832,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2934,42 +2866,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2981,25 +2926,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3011,40 +2972,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3057,21 +3034,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3083,44 +3070,55 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "statistics" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3128,31 +3126,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3194,13 +3189,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -3211,19 +3206,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -3235,41 +3226,44 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, backref='resolved_by') - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, backref="resolved_by") + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3280,8 +3274,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3292,7 +3285,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3328,26 +3321,25 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, } return data @@ -3358,18 +3350,17 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3378,26 +3369,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3410,8 +3398,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3427,64 +3415,49 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + target_ref = Column("other_ref", Unicode(255), nullable=False) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -3493,15 +3466,16 @@ class _PullRequestBase(BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -3513,13 +3487,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3527,9 +3499,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3549,7 +3519,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3560,7 +3530,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -3571,97 +3541,82 @@ class _PullRequestBase(BaseModel): if with_merge_state: merge_status = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status[0], - 'message': safe_str(merge_status[1]), + "status": merge_status[0], + "message": safe_str(merge_status[1]), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus', - cascade="all, delete, delete-orphan") - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3672,7 +3627,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3680,35 +3635,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3726,49 +3676,47 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(workspace_id) return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -3790,10 +3738,9 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) @hybrid_property @@ -3806,80 +3753,72 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3909,20 +3848,24 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3930,38 +3873,38 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -3979,6 +3922,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -3989,8 +3933,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4000,54 +3944,49 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -4091,31 +4030,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4123,120 +4059,123 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_glob(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_glob(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -4247,29 +4186,27 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - source_branch_regex = re.compile( - '^' + glob2re(self.source_branch_pattern) + '$') + source_branch_regex = re.compile("^" + glob2re(self.source_branch_pattern) + "$") source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - target_branch_regex = re.compile( - '^' + glob2re(self.target_branch_pattern) + '$') + target_branch_regex = re.compile("^" + glob2re(self.target_branch_pattern) + "$") target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False file_regex = re.compile(glob2re(self.file_pattern)) for filename in files_changed: @@ -4281,7 +4218,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4289,17 +4226,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -4311,10 +4248,10 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users @@ -4327,39 +4264,44 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -4368,8 +4310,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -4390,8 +4331,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -4409,6 +4349,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -4427,7 +4368,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -4447,16 +4388,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -4468,19 +4408,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -4491,93 +4431,119 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class DbSession(Base, BaseModel): - __tablename__ = 'db_session' + __tablename__ = "db_session" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_16_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_16_0_0.py index de645a4d..04e49729 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_16_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_16_0_0.py @@ -33,14 +33,32 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType) + or_, + and_, + not_, + func, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, +) from sqlalchemy.sql.expression import true, false from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -52,18 +70,28 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, sha1_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + sha1_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -78,10 +106,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -93,8 +121,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -105,7 +133,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -129,18 +157,16 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts base_table_args = { - 'extend_existing': True, - 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', - 'sqlite_autoincrement': True + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, } @@ -153,18 +179,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -172,27 +197,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -203,20 +227,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -227,11 +251,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -288,48 +317,47 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = ( - UniqueConstraint('app_settings_name'), - base_table_args - ) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), base_table_args) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -339,14 +367,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -358,7 +385,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -369,99 +396,75 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val @classmethod def get_by_prefix(cls, prefix): - return RhodeCodeSetting.query()\ - .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ - .all() + return RhodeCodeSetting.query().filter(RhodeCodeSetting.app_settings_name.startswith(prefix)).all() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = ( - UniqueConstraint('ui_key'), - base_table_args - ) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), base_table_args) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - base_table_args + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -471,7 +474,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -491,62 +494,60 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - base_table_args + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - base_table_args + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + base_table_args, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -557,57 +558,63 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -620,6 +627,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -627,6 +635,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -636,11 +645,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -653,10 +664,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -665,10 +678,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] @property @@ -677,27 +687,23 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -706,25 +712,24 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -732,10 +737,11 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -743,19 +749,20 @@ class User(Base, BaseModel): hash_tokens = [] user_tokens = tokens_q.all() - log.debug('Found %s user tokens to check for authentication', len(user_tokens)) + log.debug("Found %s user tokens to check for authentication", len(user_tokens)) for token in user_tokens: - log.debug('AUTH_TOKEN: checking if user token with id `%s` matches', - token.user_api_key_id) + log.debug("AUTH_TOKEN: checking if user token with id `%s` matches", token.user_api_key_id) # verify scope first, since it's way faster than hash calculation of # encrypted tokens if token.repo_id: # token has a scope, we need to verify it if scope_repo_id != token.repo_id: log.debug( - 'AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - token.repo, scope_repo_id) + "AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + token.repo, + scope_repo_id, + ) # token has a scope, and it doesn't match, skip token continue @@ -783,29 +790,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -816,6 +822,7 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -831,44 +838,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -876,7 +880,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -885,8 +888,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -898,9 +900,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -912,6 +913,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -930,13 +932,13 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -946,13 +948,10 @@ class User(Base, BaseModel): @classmethod def get_first_super_admin(cls): - user = User.query()\ - .filter(User.admin == true()) \ - .order_by(User.user_id.asc()) \ - .first() + user = User.query().filter(User.admin == true()).order_by(User.user_id.asc()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -960,14 +959,13 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -976,14 +974,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -997,97 +996,89 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key', unique=True), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - base_table_args + Index("uak_api_key_idx", "api_key", unique=True), + Index("uak_api_key_expires_idx", "api_key", "expires"), + base_table_args, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1095,12 +1086,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1112,11 +1104,11 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -1127,8 +1119,8 @@ class UserApiKeys(Base, BaseModel): if self.repo: return repr(self.repo) if self.repo_group: - return repr(self.repo_group) + ' (recursive)' - return 'global' + return repr(self.repo_group) + " (recursive)" + return "global" @property def scope_humanized(self): @@ -1141,25 +1133,20 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' - __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - base_table_args - ) - + __tablename__ = "user_email_map" + __table_args__ = (Index("uem_email_idx", "email"), UniqueConstraint("email"), base_table_args) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1172,23 +1159,20 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' - __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - base_table_args - ) - + __tablename__ = "user_ip_map" + __table_args__ = (UniqueConstraint("user_id", "ip_addr"), base_table_args) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1198,43 +1182,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - base_table_args + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + base_table_args, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1244,41 +1224,47 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "user_logs" + __table_args__ = (base_table_args,) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1289,34 +1275,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "users_groups" + __table_args__ = (base_table_args,) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1331,6 +1321,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1351,29 +1342,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1383,15 +1369,14 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): """ Permissions for user groups """ - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: @@ -1415,9 +1400,11 @@ class UserGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1442,9 +1429,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1455,11 +1444,12 @@ class UserGroup(Base, BaseModel): perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1470,13 +1460,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1484,205 +1474,183 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - base_table_args, + __tablename__ = "users_groups_members" + __table_args__ = (base_table_args,) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field + UniqueConstraint("repository_id", "field_key"), # no-multi field base_table_args, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), + Index("r_repo_name_idx", "repo_name", mysql_length=255), base_table_args, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - archived = Column( - "archived", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + archived = Column("archived", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1691,13 +1659,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1743,13 +1712,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1781,14 +1749,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True, archived=False): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True, archived=False): q = Repository.query() if not archived: @@ -1834,7 +1800,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1852,8 +1818,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1871,12 +1836,8 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - return CacheKey.query()\ - .filter(CacheKey.cache_args == invalidation_namespace)\ - .order_by(CacheKey.cache_key)\ - .all() + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + return CacheKey.query().filter(CacheKey.cache_args == invalidation_namespace).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -1885,16 +1846,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -1903,10 +1860,8 @@ class Repository(Base, BaseModel): return [] def shadow_repos(self): - shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id) - return [ - x for x in os.listdir(os.path.dirname(self.repo_full_path)) - if x.startswith(shadow_repos_pattern)] + shadow_repos_pattern = ".__shadow_repo_{}".format(self.repo_id) + return [x for x in os.listdir(os.path.dirname(self.repo_full_path)) if x.startswith(shadow_repos_pattern)] def get_new_name(self, repo_name): """ @@ -1923,13 +1878,14 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): """ Permissions for repositories """ - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: @@ -1955,9 +1911,11 @@ class Repository(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1986,11 +1944,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2017,33 +1976,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2091,7 +2048,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2104,40 +2061,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -2151,9 +2106,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2161,54 +2117,52 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides if not uri_tmpl: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI request = get_current_request() - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + request=request, uri_tmpl=uri_tmpl, repo_name=self.repo_name, repo_id=self.repo_id, **override + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2218,8 +2172,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2246,14 +2199,14 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) empty = scm_repo.is_empty() if not empty: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -2261,33 +2214,33 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.utcnow() - last_change = cs_cache.get('date') or _default + last_change = cs_cache.get("date") or _default if self.updated_on and self.updated_on > last_change: # we check if last update is newer than the new value # if yes, we use the current timestamp instead. Imagine you get # old commit pushed 1y ago, we'd set last update 1y to ago. last_change = _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2303,8 +2256,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2318,19 +2270,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2350,8 +2297,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2363,9 +2309,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2375,10 +2321,9 @@ class Repository(Base, BaseModel): def _get_instance_cached(self): from rhodecode.lib import rc_cache - cache_namespace_uid = f'repo_instance.{self.repo_id}' - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) + cache_namespace_uid = f"repo_instance.{self.repo_id}" + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + region = rc_cache.get_or_create_region("cache_repo_longterm", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) def get_instance_cached(repo_id, context_id): @@ -2388,8 +2333,8 @@ class Repository(Base, BaseModel): # because each thread of gevent needs it's own not shared connection and cache # we also alter `args` so the cache key is individual for every green thread. inv_context_manager = rc_cache.InvalidationContext( - uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, - thread_scoped=True) + uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, thread_scoped=True + ) with inv_context_manager as invalidation_context: args = (self.repo_id, inv_context_manager.cache_key) # re-compute and store cache if we get invalidate signal @@ -2398,80 +2343,84 @@ class Repository(Base, BaseModel): else: instance = get_instance_cached(*args) - log.debug( - 'Repo instance fetched in %.4fs', inv_context_manager.compute_time) + log.debug("Repo instance fetched in %.4fs", inv_context_manager.compute_time) return instance def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), + UniqueConstraint("group_name", "group_parent_id"), base_table_args, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2482,12 +2431,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2497,14 +2445,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2513,15 +2459,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user) \ - .order_by(cls.group_id.asc()) \ - .first() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).order_by(cls.group_id.asc()).first() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2547,14 +2488,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2582,9 +2526,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2633,15 +2575,14 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): """ Permissions for repository groups """ - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: @@ -2665,9 +2606,11 @@ class RepoGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2691,11 +2634,12 @@ class RepoGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoGroupToPerm.query().filter( - UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2713,130 +2657,118 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), + Index("p_perm_name_idx", "permission_name"), base_table_args, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch, for backward compat we need same value as before so forced pushed - 'branch.push_force', + "branch.push_force", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2844,9 +2776,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2854,24 +2784,26 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms(cls, user_id, repo_id=None): - q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ - .join( - Permission, - UserToRepoBranchPermission.permission_id == Permission.permission_id) \ - .join( - UserRepoToPerm, - UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ + q = ( + Session() + .query(UserToRepoBranchPermission, UserRepoToPerm, Permission) + .join(Permission, UserToRepoBranchPermission.permission_id == Permission.permission_id) + .join(UserRepoToPerm, UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) @@ -2879,46 +2811,33 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ - .join( - Permission, - UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ + q = ( + Session() + .query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) + .join(Permission, UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) .join( UserGroupRepoToPerm, - UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id, + ) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) @@ -2926,102 +2845,81 @@ class Permission(Base, BaseModel): @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserRepoGroupToPerm.permission_id == Permission.permission_id)\ - .join( - RepoGroup, - UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - base_table_args - ) + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id", "permission_id"), base_table_args) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -3033,24 +2931,27 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - base_table_args + __tablename__ = "user_user_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "user_group_id", "permission_id"), base_table_args) + + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -3062,43 +2963,52 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - base_table_args - ) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), base_table_args) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - base_table_args + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), base_table_args) + + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') - user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") + user_group_branch_perms = relationship("UserGroupToRepoBranchPermission", cascade="all") @classmethod def create(cls, users_group, repository, permission): @@ -3110,25 +3020,42 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - base_table_args + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + base_table_args, ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None + ) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3140,39 +3067,54 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - base_table_args + UniqueConstraint( + "users_group_id", + "permission_id", + ), + base_table_args, ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - base_table_args + __tablename__ = "user_repo_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "group_id", "permission_id"), base_table_args) + + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3185,20 +3127,28 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - base_table_args + __tablename__ = "users_group_repo_group_to_perm" + __table_args__ = (UniqueConstraint("users_group_id", "group_id"), base_table_args) + + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3210,43 +3160,51 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - base_table_args - ) + __tablename__ = "statistics" + __table_args__ = base_table_args stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - base_table_args + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + base_table_args, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3254,33 +3212,31 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), base_table_args, ) - CACHE_TYPE_FEED = 'FEED' - CACHE_TYPE_README = 'README' + CACHE_TYPE_FEED = "FEED" + CACHE_TYPE_README = "README" # namespaces used to register process/thread aware caches - REPO_INVALIDATION_NAMESPACE = 'repo_cache:{repo_id}' - SETTINGS_INVALIDATION_NAMESPACE = 'system_settings' + REPO_INVALIDATION_NAMESPACE = "repo_cache:{repo_id}" + SETTINGS_INVALIDATION_NAMESPACE = "system_settings" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3323,18 +3279,14 @@ class CacheKey(Base, BaseModel): qry = Session().query(cls).filter(cls.cache_args == cache_uid) if delete: qry.delete() - log.debug('cache objects deleted for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects deleted for cache args %s", safe_str(cache_uid)) else: qry.update({"cache_active": False}) - log.debug('cache objects marked as invalid for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects marked as invalid for cache args %s", safe_str(cache_uid)) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for cache args %s', - safe_str(cache_uid)) + log.exception("Cache key invalidation failed for cache args %s", safe_str(cache_uid)) Session().rollback() @classmethod @@ -3346,43 +3298,47 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), + Index("cc_revision_idx", "revision"), base_table_args, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') - resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, back_populates="resolved_by") + resolved_by = relationship("ChangesetComment", back_populates="resolved_comment") - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3393,8 +3349,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3405,7 +3360,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3441,26 +3396,25 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, } return data @@ -3471,18 +3425,18 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - base_table_args + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + base_table_args, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3491,26 +3445,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3523,8 +3474,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3540,51 +3491,40 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" # available states - STATE_CREATING = u'creating' - STATE_UPDATING = u'updating' - STATE_MERGING = u'merging' - STATE_CREATED = u'created' + STATE_CREATING = "creating" + STATE_UPDATING = "updating" + STATE_MERGING = "merging" + STATE_CREATED = "created" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) - description_renderer = Column('description_renderer', Unicode(64), nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + description_renderer = Column("description_renderer", Unicode(64), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) pull_request_state = Column("pull_request_state", String(255), nullable=True) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _source_ref = Column('org_ref', Unicode(255), nullable=False) + _source_ref = Column("org_ref", Unicode(255), nullable=False) @hybrid_property def source_ref(self): @@ -3592,13 +3532,12 @@ class _PullRequestBase(BaseModel): @source_ref.setter def source_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._source_ref = safe_str(val) - _target_ref = Column('other_ref', Unicode(255), nullable=False) + _target_ref = Column("other_ref", Unicode(255), nullable=False) @hybrid_property def target_ref(self): @@ -3606,33 +3545,28 @@ class _PullRequestBase(BaseModel): @target_ref.setter def target_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._target_ref = safe_str(val) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -3641,15 +3575,16 @@ class _PullRequestBase(BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -3661,13 +3596,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3675,9 +3608,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3698,7 +3629,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3710,7 +3641,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -3721,96 +3652,80 @@ class _PullRequestBase(BaseModel): if with_merge_state: merge_status = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status[0], - 'message': safe_str(merge_status[1]), + "status": merge_status[0], + "message": safe_str(merge_status[1]), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_requests" + __table_args__ = (base_table_args,) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus', - cascade="all, delete, delete-orphan") - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3821,7 +3736,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3829,35 +3744,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3875,49 +3785,46 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - self.target_repo.repo_id, workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(self.target_repo.repo_id, workspace_id) if os.path.isdir(shadow_repository_path): return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_versions" + __table_args__ = (base_table_args,) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -3939,10 +3846,8 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = (base_table_args,) @hybrid_property def reasons(self): @@ -3954,79 +3859,72 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), + Index("notification_type_idx", "type"), base_table_args, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -4058,20 +3956,22 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' - __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - base_table_args + __tablename__ = "user_to_notification" + __table_args__ = (UniqueConstraint("user_id", "notification_id"), base_table_args) + + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) - - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -4079,38 +3979,39 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - base_table_args + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + base_table_args, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -4128,6 +4029,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -4138,8 +4040,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4149,47 +4051,46 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - base_table_args + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + base_table_args, ) - external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): @@ -4237,36 +4138,30 @@ class ExternalIdentity(Base, BaseModel): @classmethod def load_provider_plugin(cls, plugin_id): from rhodecode.authentication.base import loadplugin - _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) + + _plugin_id = "egg:rhodecode-enterprise-ee#{}".format(plugin_id) auth_plugin = loadplugin(_plugin_id) return auth_plugin class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - base_table_args - ) + __tablename__ = "integrations" + __table_args__ = base_table_args - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4274,118 +4169,109 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = base_table_args - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = base_table_args VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules" + __table_args__ = base_table_args - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_pattern(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_pattern(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_pattern(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -4396,37 +4282,37 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - if self.source_branch_pattern.startswith('re:'): + if self.source_branch_pattern.startswith("re:"): source_pattern = self.source_branch_pattern[3:] else: - source_pattern = '^' + glob2re(self.source_branch_pattern) + '$' + source_pattern = "^" + glob2re(self.source_branch_pattern) + "$" source_branch_regex = re.compile(source_pattern) source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - if self.target_branch_pattern.startswith('re:'): + if self.target_branch_pattern.startswith("re:"): target_pattern = self.target_branch_pattern[3:] else: - target_pattern = '^' + glob2re(self.target_branch_pattern) + '$' + target_pattern = "^" + glob2re(self.target_branch_pattern) + "$" target_branch_regex = re.compile(target_pattern) target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False - if self.file_pattern.startswith('re:'): + if self.file_pattern.startswith("re:"): file_pattern = self.file_pattern[3:] else: file_pattern = glob2re(self.file_pattern) @@ -4440,7 +4326,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4448,17 +4334,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -4470,16 +4356,15 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def user_group_vote_rule(self, user_id): - rules = [] if not self.rule_user_groups: return rules @@ -4491,39 +4376,45 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), base_table_args, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -4532,8 +4423,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -4554,8 +4444,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -4573,6 +4462,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -4591,7 +4481,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -4611,16 +4501,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -4632,19 +4521,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -4655,79 +4544,105 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_migrate_version" + __table_args__ = (base_table_args,) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) @classmethod def set_version(cls, version): @@ -4740,16 +4655,14 @@ class DbMigrateVersion(Base, BaseModel): class DbSession(Base, BaseModel): - __tablename__ = 'db_session' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_session" + __table_args__ = (base_table_args,) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_16_0_1.py b/rhodecode/lib/dbmigrate/schema/db_4_16_0_1.py index 6cad7b0c..665ab343 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_16_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_16_0_1.py @@ -33,14 +33,32 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType) + or_, + and_, + not_, + func, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, +) from sqlalchemy.sql.expression import true, false from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -52,18 +70,28 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, sha1_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + sha1_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -78,10 +106,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -93,8 +121,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -105,7 +133,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -129,18 +157,16 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts base_table_args = { - 'extend_existing': True, - 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', - 'sqlite_autoincrement': True + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, } @@ -153,18 +179,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -172,27 +197,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -203,20 +227,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -227,11 +251,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -288,48 +317,47 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = ( - UniqueConstraint('app_settings_name'), - base_table_args - ) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), base_table_args) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -339,14 +367,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -358,7 +385,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -369,99 +396,75 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val @classmethod def get_by_prefix(cls, prefix): - return RhodeCodeSetting.query()\ - .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ - .all() + return RhodeCodeSetting.query().filter(RhodeCodeSetting.app_settings_name.startswith(prefix)).all() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = ( - UniqueConstraint('ui_key'), - base_table_args - ) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), base_table_args) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - base_table_args + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -471,7 +474,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -491,62 +494,60 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - base_table_args + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - base_table_args + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + base_table_args, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -557,57 +558,63 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -620,6 +627,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -627,6 +635,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -636,11 +645,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -653,10 +664,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -665,10 +678,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] @property @@ -677,27 +687,23 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -706,25 +712,24 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -732,10 +737,11 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -743,19 +749,20 @@ class User(Base, BaseModel): hash_tokens = [] user_tokens = tokens_q.all() - log.debug('Found %s user tokens to check for authentication', len(user_tokens)) + log.debug("Found %s user tokens to check for authentication", len(user_tokens)) for token in user_tokens: - log.debug('AUTH_TOKEN: checking if user token with id `%s` matches', - token.user_api_key_id) + log.debug("AUTH_TOKEN: checking if user token with id `%s` matches", token.user_api_key_id) # verify scope first, since it's way faster than hash calculation of # encrypted tokens if token.repo_id: # token has a scope, we need to verify it if scope_repo_id != token.repo_id: log.debug( - 'AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - token.repo, scope_repo_id) + "AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + token.repo, + scope_repo_id, + ) # token has a scope, and it doesn't match, skip token continue @@ -783,29 +790,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -816,6 +822,7 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -831,44 +838,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -876,7 +880,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -885,8 +888,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -898,9 +900,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -912,6 +913,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -930,13 +932,13 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -946,13 +948,10 @@ class User(Base, BaseModel): @classmethod def get_first_super_admin(cls): - user = User.query()\ - .filter(User.admin == true()) \ - .order_by(User.user_id.asc()) \ - .first() + user = User.query().filter(User.admin == true()).order_by(User.user_id.asc()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -969,7 +968,7 @@ class User(Base, BaseModel): def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -978,14 +977,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -999,97 +999,89 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key', unique=True), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - base_table_args + Index("uak_api_key_idx", "api_key", unique=True), + Index("uak_api_key_expires_idx", "api_key", "expires"), + base_table_args, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1097,12 +1089,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1114,11 +1107,11 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -1127,10 +1120,10 @@ class UserApiKeys(Base, BaseModel): def _get_scope(self): if self.repo: - return 'Repository: {}'.format(self.repo.repo_name) + return "Repository: {}".format(self.repo.repo_name) if self.repo_group: - return 'RepositoryGroup: {} (recursive)'.format(self.repo_group.group_name) - return 'Global' + return "RepositoryGroup: {} (recursive)".format(self.repo_group.group_name) + return "Global" @property def scope_humanized(self): @@ -1143,25 +1136,20 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' - __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - base_table_args - ) - + __tablename__ = "user_email_map" + __table_args__ = (Index("uem_email_idx", "email"), UniqueConstraint("email"), base_table_args) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1174,23 +1162,20 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' - __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - base_table_args - ) - + __tablename__ = "user_ip_map" + __table_args__ = (UniqueConstraint("user_id", "ip_addr"), base_table_args) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1200,43 +1185,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - base_table_args + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + base_table_args, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1246,41 +1227,47 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "user_logs" + __table_args__ = (base_table_args,) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1291,34 +1278,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "users_groups" + __table_args__ = (base_table_args,) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1333,6 +1324,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1353,29 +1345,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1385,16 +1372,14 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for user groups """ - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: @@ -1418,9 +1403,11 @@ class UserGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1450,29 +1437,30 @@ class UserGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupUserGroupToPerm.query()\ - .filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.user_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1483,13 +1471,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1497,205 +1485,183 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - base_table_args, + __tablename__ = "users_groups_members" + __table_args__ = (base_table_args,) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field + UniqueConstraint("repository_id", "field_key"), # no-multi field base_table_args, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), + Index("r_repo_name_idx", "repo_name", mysql_length=255), base_table_args, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - archived = Column( - "archived", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + archived = Column("archived", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1704,13 +1670,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1756,13 +1723,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1794,14 +1760,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True, archived=False): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True, archived=False): q = Repository.query() if not archived: @@ -1847,7 +1811,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1865,8 +1829,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1884,12 +1847,8 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - return CacheKey.query()\ - .filter(CacheKey.cache_args == invalidation_namespace)\ - .order_by(CacheKey.cache_key)\ - .all() + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + return CacheKey.query().filter(CacheKey.cache_args == invalidation_namespace).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -1898,16 +1857,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -1916,10 +1871,8 @@ class Repository(Base, BaseModel): return [] def shadow_repos(self): - shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id) - return [ - x for x in os.listdir(os.path.dirname(self.repo_full_path)) - if x.startswith(shadow_repos_pattern)] + shadow_repos_pattern = ".__shadow_repo_{}".format(self.repo_id) + return [x for x in os.listdir(os.path.dirname(self.repo_full_path)) if x.startswith(shadow_repos_pattern)] def get_new_name(self, repo_name): """ @@ -1936,14 +1889,14 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repositories """ - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: @@ -1969,9 +1922,11 @@ class Repository(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2006,19 +1961,19 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=True): - q = UserGroupRepoToPerm.query()\ - .filter(UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2040,33 +1995,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2114,7 +2067,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2127,40 +2080,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -2174,9 +2125,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2184,54 +2136,52 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides if not uri_tmpl: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI request = get_current_request() - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + request=request, uri_tmpl=uri_tmpl, repo_name=self.repo_name, repo_id=self.repo_id, **override + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2241,8 +2191,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2269,14 +2218,14 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) empty = not scm_repo or scm_repo.is_empty() if not empty: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -2284,33 +2233,33 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.utcnow() - last_change = cs_cache.get('date') or _default + last_change = cs_cache.get("date") or _default if self.updated_on and self.updated_on > last_change: # we check if last update is newer than the new value # if yes, we use the current timestamp instead. Imagine you get # old commit pushed 1y ago, we'd set last update 1y to ago. last_change = _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2326,8 +2275,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2341,19 +2289,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2373,8 +2316,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2386,9 +2328,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2398,10 +2340,9 @@ class Repository(Base, BaseModel): def _get_instance_cached(self): from rhodecode.lib import rc_cache - cache_namespace_uid = f'repo_instance.{self.repo_id}' - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) + cache_namespace_uid = f"repo_instance.{self.repo_id}" + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + region = rc_cache.get_or_create_region("cache_repo_longterm", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) def get_instance_cached(repo_id, context_id): @@ -2411,8 +2352,8 @@ class Repository(Base, BaseModel): # because each thread of gevent needs it's own not shared connection and cache # we also alter `args` so the cache key is individual for every green thread. inv_context_manager = rc_cache.InvalidationContext( - uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, - thread_scoped=True) + uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, thread_scoped=True + ) with inv_context_manager as invalidation_context: args = (self.repo_id, inv_context_manager.cache_key) # re-compute and store cache if we get invalidate signal @@ -2421,80 +2362,84 @@ class Repository(Base, BaseModel): else: instance = get_instance_cached(*args) - log.debug( - 'Repo instance fetched in %.4fs', inv_context_manager.compute_time) + log.debug("Repo instance fetched in %.4fs", inv_context_manager.compute_time) return instance def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), + UniqueConstraint("group_name", "group_parent_id"), base_table_args, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2505,12 +2450,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2520,14 +2464,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2536,15 +2478,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user) \ - .order_by(cls.group_id.asc()) \ - .first() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).order_by(cls.group_id.asc()).first() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2570,14 +2507,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2605,9 +2545,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2656,16 +2594,14 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repository groups """ - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: @@ -2689,9 +2625,11 @@ class RepoGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2721,19 +2659,19 @@ class RepoGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupRepoGroupToPerm.query()\ - .filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2746,130 +2684,118 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), + Index("p_perm_name_idx", "permission_name"), base_table_args, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch, for backward compat we need same value as before so forced pushed - 'branch.push_force', + "branch.push_force", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2877,9 +2803,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2887,24 +2811,26 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms(cls, user_id, repo_id=None): - q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ - .join( - Permission, - UserToRepoBranchPermission.permission_id == Permission.permission_id) \ - .join( - UserRepoToPerm, - UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ + q = ( + Session() + .query(UserToRepoBranchPermission, UserRepoToPerm, Permission) + .join(Permission, UserToRepoBranchPermission.permission_id == Permission.permission_id) + .join(UserRepoToPerm, UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) @@ -2912,46 +2838,33 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ - .join( - Permission, - UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ + q = ( + Session() + .query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) + .join(Permission, UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) .join( UserGroupRepoToPerm, - UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id, + ) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) @@ -2959,102 +2872,81 @@ class Permission(Base, BaseModel): @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserRepoGroupToPerm.permission_id == Permission.permission_id)\ - .join( - RepoGroup, - UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - base_table_args - ) + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id", "permission_id"), base_table_args) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -3066,24 +2958,27 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - base_table_args + __tablename__ = "user_user_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "user_group_id", "permission_id"), base_table_args) + + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -3095,43 +2990,52 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - base_table_args - ) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), base_table_args) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - base_table_args + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), base_table_args) + + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') - user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") + user_group_branch_perms = relationship("UserGroupToRepoBranchPermission", cascade="all") @classmethod def create(cls, users_group, repository, permission): @@ -3143,25 +3047,42 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - base_table_args + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + base_table_args, ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None + ) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3173,39 +3094,54 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - base_table_args + UniqueConstraint( + "users_group_id", + "permission_id", + ), + base_table_args, ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - base_table_args + __tablename__ = "user_repo_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "group_id", "permission_id"), base_table_args) + + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3218,20 +3154,28 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - base_table_args + __tablename__ = "users_group_repo_group_to_perm" + __table_args__ = (UniqueConstraint("users_group_id", "group_id"), base_table_args) + + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3243,43 +3187,51 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - base_table_args - ) + __tablename__ = "statistics" + __table_args__ = base_table_args stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - base_table_args + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + base_table_args, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3287,33 +3239,31 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), base_table_args, ) - CACHE_TYPE_FEED = 'FEED' - CACHE_TYPE_README = 'README' + CACHE_TYPE_FEED = "FEED" + CACHE_TYPE_README = "README" # namespaces used to register process/thread aware caches - REPO_INVALIDATION_NAMESPACE = 'repo_cache:{repo_id}' - SETTINGS_INVALIDATION_NAMESPACE = 'system_settings' + REPO_INVALIDATION_NAMESPACE = "repo_cache:{repo_id}" + SETTINGS_INVALIDATION_NAMESPACE = "system_settings" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3356,18 +3306,14 @@ class CacheKey(Base, BaseModel): qry = Session().query(cls).filter(cls.cache_args == cache_uid) if delete: qry.delete() - log.debug('cache objects deleted for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects deleted for cache args %s", safe_str(cache_uid)) else: qry.update({"cache_active": False}) - log.debug('cache objects marked as invalid for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects marked as invalid for cache args %s", safe_str(cache_uid)) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for cache args %s', - safe_str(cache_uid)) + log.exception("Cache key invalidation failed for cache args %s", safe_str(cache_uid)) Session().rollback() @classmethod @@ -3379,43 +3325,47 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), + Index("cc_revision_idx", "revision"), base_table_args, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') - resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, back_populates="resolved_by") + resolved_by = relationship("ChangesetComment", back_populates="resolved_comment") - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3426,8 +3376,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3438,7 +3387,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3474,26 +3423,25 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, } return data @@ -3504,18 +3452,18 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - base_table_args + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + base_table_args, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3524,26 +3472,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3556,8 +3501,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3579,15 +3524,13 @@ class _SetState(object): self._pr_state = pr_state def __enter__(self): - log.debug('StateLock: entering set state context, setting state to: `%s`', - self._pr_state) + log.debug("StateLock: entering set state context, setting state to: `%s`", self._pr_state) self._pr.pull_request_state = self._pr_state Session().add(self._pr) Session().commit() def __exit__(self, exc_type, exc_val, exc_tb): - log.debug('StateLock: exiting set state context, setting state to: `%s`', - self._org_state) + log.debug("StateLock: exiting set state context, setting state to: `%s`", self._org_state) self._pr.pull_request_state = self._org_state Session().add(self._pr) Session().commit() @@ -3599,51 +3542,40 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" # available states - STATE_CREATING = u'creating' - STATE_UPDATING = u'updating' - STATE_MERGING = u'merging' - STATE_CREATED = u'created' + STATE_CREATING = "creating" + STATE_UPDATING = "updating" + STATE_MERGING = "merging" + STATE_CREATED = "created" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) - description_renderer = Column('description_renderer', Unicode(64), nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + description_renderer = Column("description_renderer", Unicode(64), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) pull_request_state = Column("pull_request_state", String(255), nullable=True) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _source_ref = Column('org_ref', Unicode(255), nullable=False) + _source_ref = Column("org_ref", Unicode(255), nullable=False) @hybrid_property def source_ref(self): @@ -3651,13 +3583,12 @@ class _PullRequestBase(BaseModel): @source_ref.setter def source_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._source_ref = safe_str(val) - _target_ref = Column('other_ref', Unicode(255), nullable=False) + _target_ref = Column("other_ref", Unicode(255), nullable=False) @hybrid_property def target_ref(self): @@ -3665,33 +3596,28 @@ class _PullRequestBase(BaseModel): @target_ref.setter def target_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._target_ref = safe_str(val) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -3700,15 +3626,16 @@ class _PullRequestBase(BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -3720,13 +3647,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3734,9 +3659,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3757,7 +3680,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3769,7 +3692,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -3780,63 +3703,57 @@ class _PullRequestBase(BaseModel): if with_merge_state: merge_status = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status[0], - 'message': safe_str(merge_status[1]), + "status": merge_status[0], + "message": safe_str(merge_status[1]), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'state': pull_request.pull_request_state, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "state": pull_request.pull_request_state, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data @@ -3857,34 +3774,24 @@ class _PullRequestBase(BaseModel): class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_requests" + __table_args__ = (base_table_args,) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus', - cascade="all, delete, delete-orphan") - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3895,7 +3802,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3903,35 +3810,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3949,49 +3851,46 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - self.target_repo.repo_id, workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(self.target_repo.repo_id, workspace_id) if os.path.isdir(shadow_repository_path): return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_versions" + __table_args__ = (base_table_args,) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -4013,10 +3912,8 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = (base_table_args,) @hybrid_property def reasons(self): @@ -4028,79 +3925,72 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), + Index("notification_type_idx", "type"), base_table_args, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -4132,20 +4022,22 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' - __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - base_table_args + __tablename__ = "user_to_notification" + __table_args__ = (UniqueConstraint("user_id", "notification_id"), base_table_args) + + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) - - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -4153,38 +4045,39 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - base_table_args + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + base_table_args, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -4202,6 +4095,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -4212,8 +4106,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4223,47 +4117,46 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - base_table_args + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + base_table_args, ) - external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): @@ -4311,36 +4204,30 @@ class ExternalIdentity(Base, BaseModel): @classmethod def load_provider_plugin(cls, plugin_id): from rhodecode.authentication.base import loadplugin - _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) + + _plugin_id = "egg:rhodecode-enterprise-ee#{}".format(plugin_id) auth_plugin = loadplugin(_plugin_id) return auth_plugin class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - base_table_args - ) + __tablename__ = "integrations" + __table_args__ = base_table_args - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4348,118 +4235,109 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = base_table_args - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = base_table_args VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules" + __table_args__ = base_table_args - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_pattern(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_pattern(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_pattern(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -4470,37 +4348,37 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - if self.source_branch_pattern.startswith('re:'): + if self.source_branch_pattern.startswith("re:"): source_pattern = self.source_branch_pattern[3:] else: - source_pattern = '^' + glob2re(self.source_branch_pattern) + '$' + source_pattern = "^" + glob2re(self.source_branch_pattern) + "$" source_branch_regex = re.compile(source_pattern) source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - if self.target_branch_pattern.startswith('re:'): + if self.target_branch_pattern.startswith("re:"): target_pattern = self.target_branch_pattern[3:] else: - target_pattern = '^' + glob2re(self.target_branch_pattern) + '$' + target_pattern = "^" + glob2re(self.target_branch_pattern) + "$" target_branch_regex = re.compile(target_pattern) target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False - if self.file_pattern.startswith('re:'): + if self.file_pattern.startswith("re:"): file_pattern = self.file_pattern[3:] else: file_pattern = glob2re(self.file_pattern) @@ -4514,7 +4392,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4522,17 +4400,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -4544,16 +4422,15 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def user_group_vote_rule(self, user_id): - rules = [] if not self.rule_user_groups: return rules @@ -4565,39 +4442,45 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), base_table_args, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -4606,8 +4489,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -4628,8 +4510,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -4647,6 +4528,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -4665,7 +4547,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -4685,16 +4567,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -4706,19 +4587,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -4729,88 +4610,122 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class UserBookmark(Base, BaseModel): - __tablename__ = 'user_bookmarks' + __tablename__ = "user_bookmarks" __table_args__ = ( - UniqueConstraint('user_id', 'bookmark_repo_id'), - UniqueConstraint('user_id', 'bookmark_repo_group_id'), - UniqueConstraint('user_id', 'bookmark_position'), - base_table_args + UniqueConstraint("user_id", "bookmark_repo_id"), + UniqueConstraint("user_id", "bookmark_repo_group_id"), + UniqueConstraint("user_id", "bookmark_position"), + base_table_args, ) - user_bookmark_id = Column("user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user_bookmark_id = Column( + "user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) position = Column("bookmark_position", Integer(), nullable=False) title = Column("bookmark_title", String(255), nullable=True, unique=None, default=None) redirect_url = Column("bookmark_redirect_url", String(10240), nullable=True, unique=None, default=None) created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - bookmark_repo_id = Column("bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) - bookmark_repo_group_id = Column("bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None) + bookmark_repo_id = Column( + "bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + bookmark_repo_group_id = Column( + "bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) user = relationship("User") @@ -4819,14 +4734,12 @@ class UserBookmark(Base, BaseModel): class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_migrate_version" + __table_args__ = (base_table_args,) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) @classmethod def set_version(cls, version): @@ -4839,16 +4752,14 @@ class DbMigrateVersion(Base, BaseModel): class DbSession(Base, BaseModel): - __tablename__ = 'db_session' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_session" + __table_args__ = (base_table_args,) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_16_0_2.py b/rhodecode/lib/dbmigrate/schema/db_4_16_0_2.py index 4d922f1a..0d5adf47 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_16_0_2.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_16_0_2.py @@ -33,14 +33,32 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType) + or_, + and_, + not_, + func, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, +) from sqlalchemy.sql.expression import true, false from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -52,18 +70,28 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, sha1_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + sha1_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -78,10 +106,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -93,8 +121,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -105,7 +133,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -129,18 +157,16 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts base_table_args = { - 'extend_existing': True, - 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', - 'sqlite_autoincrement': True + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, } @@ -153,18 +179,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -172,27 +197,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -203,20 +227,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -227,11 +251,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -288,48 +317,47 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = ( - UniqueConstraint('app_settings_name'), - base_table_args - ) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), base_table_args) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -339,14 +367,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -358,7 +385,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -369,99 +396,75 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val @classmethod def get_by_prefix(cls, prefix): - return RhodeCodeSetting.query()\ - .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ - .all() + return RhodeCodeSetting.query().filter(RhodeCodeSetting.app_settings_name.startswith(prefix)).all() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = ( - UniqueConstraint('ui_key'), - base_table_args - ) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), base_table_args) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - base_table_args + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -471,7 +474,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -491,62 +494,60 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - base_table_args + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - base_table_args + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + base_table_args, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -557,57 +558,63 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -620,6 +627,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -627,6 +635,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -636,11 +645,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -653,10 +664,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -665,10 +678,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] @property @@ -677,27 +687,23 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -706,25 +712,24 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -732,10 +737,11 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -743,19 +749,20 @@ class User(Base, BaseModel): hash_tokens = [] user_tokens = tokens_q.all() - log.debug('Found %s user tokens to check for authentication', len(user_tokens)) + log.debug("Found %s user tokens to check for authentication", len(user_tokens)) for token in user_tokens: - log.debug('AUTH_TOKEN: checking if user token with id `%s` matches', - token.user_api_key_id) + log.debug("AUTH_TOKEN: checking if user token with id `%s` matches", token.user_api_key_id) # verify scope first, since it's way faster than hash calculation of # encrypted tokens if token.repo_id: # token has a scope, we need to verify it if scope_repo_id != token.repo_id: log.debug( - 'AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - token.repo, scope_repo_id) + "AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + token.repo, + scope_repo_id, + ) # token has a scope, and it doesn't match, skip token continue @@ -783,29 +790,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -816,6 +822,7 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -831,44 +838,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -876,7 +880,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -885,8 +888,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -898,9 +900,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -912,6 +913,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -930,13 +932,13 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -946,13 +948,10 @@ class User(Base, BaseModel): @classmethod def get_first_super_admin(cls): - user = User.query()\ - .filter(User.admin == true()) \ - .order_by(User.user_id.asc()) \ - .first() + user = User.query().filter(User.admin == true()).order_by(User.user_id.asc()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -969,7 +968,7 @@ class User(Base, BaseModel): def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -978,14 +977,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -999,97 +999,89 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key', unique=True), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - base_table_args + Index("uak_api_key_idx", "api_key", unique=True), + Index("uak_api_key_expires_idx", "api_key", "expires"), + base_table_args, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1097,12 +1089,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1114,11 +1107,11 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -1127,10 +1120,10 @@ class UserApiKeys(Base, BaseModel): def _get_scope(self): if self.repo: - return 'Repository: {}'.format(self.repo.repo_name) + return "Repository: {}".format(self.repo.repo_name) if self.repo_group: - return 'RepositoryGroup: {} (recursive)'.format(self.repo_group.group_name) - return 'Global' + return "RepositoryGroup: {} (recursive)".format(self.repo_group.group_name) + return "Global" @property def scope_humanized(self): @@ -1143,25 +1136,20 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' - __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - base_table_args - ) - + __tablename__ = "user_email_map" + __table_args__ = (Index("uem_email_idx", "email"), UniqueConstraint("email"), base_table_args) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1174,23 +1162,20 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' - __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - base_table_args - ) - + __tablename__ = "user_ip_map" + __table_args__ = (UniqueConstraint("user_id", "ip_addr"), base_table_args) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1200,43 +1185,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - base_table_args + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + base_table_args, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1246,41 +1227,47 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "user_logs" + __table_args__ = (base_table_args,) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1291,34 +1278,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "users_groups" + __table_args__ = (base_table_args,) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1333,6 +1324,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1353,29 +1345,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1385,16 +1372,14 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for user groups """ - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: @@ -1418,9 +1403,11 @@ class UserGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1450,29 +1437,30 @@ class UserGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupUserGroupToPerm.query()\ - .filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.user_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1483,13 +1471,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1497,205 +1485,183 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - base_table_args, + __tablename__ = "users_groups_members" + __table_args__ = (base_table_args,) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field + UniqueConstraint("repository_id", "field_key"), # no-multi field base_table_args, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), + Index("r_repo_name_idx", "repo_name", mysql_length=255), base_table_args, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - archived = Column( - "archived", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + archived = Column("archived", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1704,13 +1670,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1756,13 +1723,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1794,14 +1760,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True, archived=False): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True, archived=False): q = Repository.query() if not archived: @@ -1847,7 +1811,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1865,8 +1829,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1884,12 +1847,8 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - return CacheKey.query()\ - .filter(CacheKey.cache_args == invalidation_namespace)\ - .order_by(CacheKey.cache_key)\ - .all() + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + return CacheKey.query().filter(CacheKey.cache_args == invalidation_namespace).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -1898,16 +1857,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -1916,10 +1871,8 @@ class Repository(Base, BaseModel): return [] def shadow_repos(self): - shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id) - return [ - x for x in os.listdir(os.path.dirname(self.repo_full_path)) - if x.startswith(shadow_repos_pattern)] + shadow_repos_pattern = ".__shadow_repo_{}".format(self.repo_id) + return [x for x in os.listdir(os.path.dirname(self.repo_full_path)) if x.startswith(shadow_repos_pattern)] def get_new_name(self, repo_name): """ @@ -1936,14 +1889,14 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repositories """ - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: @@ -1969,9 +1922,11 @@ class Repository(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2006,19 +1961,19 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=True): - q = UserGroupRepoToPerm.query()\ - .filter(UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2040,33 +1995,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2114,7 +2067,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2127,40 +2080,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -2174,9 +2125,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2184,54 +2136,52 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides if not uri_tmpl: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI request = get_current_request() - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + request=request, uri_tmpl=uri_tmpl, repo_name=self.repo_name, repo_id=self.repo_id, **override + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2241,8 +2191,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2269,14 +2218,14 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) empty = not scm_repo or scm_repo.is_empty() if not empty: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -2284,33 +2233,33 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.utcnow() - last_change = cs_cache.get('date') or _default + last_change = cs_cache.get("date") or _default if self.updated_on and self.updated_on > last_change: # we check if last update is newer than the new value # if yes, we use the current timestamp instead. Imagine you get # old commit pushed 1y ago, we'd set last update 1y to ago. last_change = _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2326,8 +2275,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2341,19 +2289,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2373,8 +2316,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2386,9 +2328,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2398,10 +2340,9 @@ class Repository(Base, BaseModel): def _get_instance_cached(self): from rhodecode.lib import rc_cache - cache_namespace_uid = f'repo_instance.{self.repo_id}' - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) + cache_namespace_uid = f"repo_instance.{self.repo_id}" + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + region = rc_cache.get_or_create_region("cache_repo_longterm", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) def get_instance_cached(repo_id, context_id): @@ -2411,8 +2352,8 @@ class Repository(Base, BaseModel): # because each thread of gevent needs it's own not shared connection and cache # we also alter `args` so the cache key is individual for every green thread. inv_context_manager = rc_cache.InvalidationContext( - uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, - thread_scoped=True) + uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, thread_scoped=True + ) with inv_context_manager as invalidation_context: args = (self.repo_id, inv_context_manager.cache_key) # re-compute and store cache if we get invalidate signal @@ -2421,80 +2362,84 @@ class Repository(Base, BaseModel): else: instance = get_instance_cached(*args) - log.debug( - 'Repo instance fetched in %.4fs', inv_context_manager.compute_time) + log.debug("Repo instance fetched in %.4fs", inv_context_manager.compute_time) return instance def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), + UniqueConstraint("group_name", "group_parent_id"), base_table_args, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2505,12 +2450,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2520,14 +2464,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2536,15 +2478,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user) \ - .order_by(cls.group_id.asc()) \ - .first() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).order_by(cls.group_id.asc()).first() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2570,14 +2507,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2605,9 +2545,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2656,16 +2594,14 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repository groups """ - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: @@ -2689,9 +2625,11 @@ class RepoGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2721,19 +2659,19 @@ class RepoGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupRepoGroupToPerm.query()\ - .filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2746,130 +2684,118 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), + Index("p_perm_name_idx", "permission_name"), base_table_args, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch, for backward compat we need same value as before so forced pushed - 'branch.push_force', + "branch.push_force", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2877,9 +2803,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2887,24 +2811,26 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms(cls, user_id, repo_id=None): - q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ - .join( - Permission, - UserToRepoBranchPermission.permission_id == Permission.permission_id) \ - .join( - UserRepoToPerm, - UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ + q = ( + Session() + .query(UserToRepoBranchPermission, UserRepoToPerm, Permission) + .join(Permission, UserToRepoBranchPermission.permission_id == Permission.permission_id) + .join(UserRepoToPerm, UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) @@ -2912,46 +2838,33 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ - .join( - Permission, - UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ + q = ( + Session() + .query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) + .join(Permission, UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) .join( UserGroupRepoToPerm, - UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id, + ) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) @@ -2959,102 +2872,81 @@ class Permission(Base, BaseModel): @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserRepoGroupToPerm.permission_id == Permission.permission_id)\ - .join( - RepoGroup, - UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - base_table_args - ) + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id", "permission_id"), base_table_args) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -3066,24 +2958,27 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - base_table_args + __tablename__ = "user_user_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "user_group_id", "permission_id"), base_table_args) + + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -3095,43 +2990,52 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - base_table_args - ) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), base_table_args) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - base_table_args + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), base_table_args) + + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') - user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") + user_group_branch_perms = relationship("UserGroupToRepoBranchPermission", cascade="all") @classmethod def create(cls, users_group, repository, permission): @@ -3143,25 +3047,42 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - base_table_args + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + base_table_args, ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None + ) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3173,39 +3094,54 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - base_table_args + UniqueConstraint( + "users_group_id", + "permission_id", + ), + base_table_args, ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - base_table_args + __tablename__ = "user_repo_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "group_id", "permission_id"), base_table_args) + + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3218,20 +3154,28 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - base_table_args + __tablename__ = "users_group_repo_group_to_perm" + __table_args__ = (UniqueConstraint("users_group_id", "group_id"), base_table_args) + + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3243,43 +3187,51 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - base_table_args - ) + __tablename__ = "statistics" + __table_args__ = base_table_args stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - base_table_args + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + base_table_args, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3287,33 +3239,31 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), base_table_args, ) - CACHE_TYPE_FEED = 'FEED' - CACHE_TYPE_README = 'README' + CACHE_TYPE_FEED = "FEED" + CACHE_TYPE_README = "README" # namespaces used to register process/thread aware caches - REPO_INVALIDATION_NAMESPACE = 'repo_cache:{repo_id}' - SETTINGS_INVALIDATION_NAMESPACE = 'system_settings' + REPO_INVALIDATION_NAMESPACE = "repo_cache:{repo_id}" + SETTINGS_INVALIDATION_NAMESPACE = "system_settings" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3356,18 +3306,14 @@ class CacheKey(Base, BaseModel): qry = Session().query(cls).filter(cls.cache_args == cache_uid) if delete: qry.delete() - log.debug('cache objects deleted for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects deleted for cache args %s", safe_str(cache_uid)) else: qry.update({"cache_active": False}) - log.debug('cache objects marked as invalid for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects marked as invalid for cache args %s", safe_str(cache_uid)) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for cache args %s', - safe_str(cache_uid)) + log.exception("Cache key invalidation failed for cache args %s", safe_str(cache_uid)) Session().rollback() @classmethod @@ -3379,43 +3325,47 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), + Index("cc_revision_idx", "revision"), base_table_args, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') - resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, back_populates="resolved_by") + resolved_by = relationship("ChangesetComment", back_populates="resolved_comment") - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3426,8 +3376,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3438,7 +3387,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3474,27 +3423,26 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on, - 'comment_resolved_by': self.resolved + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, + "comment_resolved_by": self.resolved, } return data @@ -3505,18 +3453,18 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - base_table_args + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + base_table_args, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3525,26 +3473,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3557,8 +3502,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3580,15 +3525,13 @@ class _SetState(object): self._pr_state = pr_state def __enter__(self): - log.debug('StateLock: entering set state context, setting state to: `%s`', - self._pr_state) + log.debug("StateLock: entering set state context, setting state to: `%s`", self._pr_state) self._pr.pull_request_state = self._pr_state Session().add(self._pr) Session().commit() def __exit__(self, exc_type, exc_val, exc_tb): - log.debug('StateLock: exiting set state context, setting state to: `%s`', - self._org_state) + log.debug("StateLock: exiting set state context, setting state to: `%s`", self._org_state) self._pr.pull_request_state = self._org_state Session().add(self._pr) Session().commit() @@ -3600,51 +3543,40 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" # available states - STATE_CREATING = u'creating' - STATE_UPDATING = u'updating' - STATE_MERGING = u'merging' - STATE_CREATED = u'created' + STATE_CREATING = "creating" + STATE_UPDATING = "updating" + STATE_MERGING = "merging" + STATE_CREATED = "created" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) - description_renderer = Column('description_renderer', Unicode(64), nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + description_renderer = Column("description_renderer", Unicode(64), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) pull_request_state = Column("pull_request_state", String(255), nullable=True) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _source_ref = Column('org_ref', Unicode(255), nullable=False) + _source_ref = Column("org_ref", Unicode(255), nullable=False) @hybrid_property def source_ref(self): @@ -3652,13 +3584,12 @@ class _PullRequestBase(BaseModel): @source_ref.setter def source_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._source_ref = safe_str(val) - _target_ref = Column('other_ref', Unicode(255), nullable=False) + _target_ref = Column("other_ref", Unicode(255), nullable=False) @hybrid_property def target_ref(self): @@ -3666,33 +3597,28 @@ class _PullRequestBase(BaseModel): @target_ref.setter def target_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._target_ref = safe_str(val) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -3701,15 +3627,16 @@ class _PullRequestBase(BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -3721,13 +3648,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3735,9 +3660,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3758,7 +3681,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3770,7 +3693,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -3781,63 +3704,57 @@ class _PullRequestBase(BaseModel): if with_merge_state: merge_status = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status[0], - 'message': safe_str(merge_status[1]), + "status": merge_status[0], + "message": safe_str(merge_status[1]), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'state': pull_request.pull_request_state, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "state": pull_request.pull_request_state, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data @@ -3858,34 +3775,24 @@ class _PullRequestBase(BaseModel): class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_requests" + __table_args__ = (base_table_args,) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus', - cascade="all, delete, delete-orphan") - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3896,7 +3803,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3904,35 +3811,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3950,49 +3852,46 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - self.target_repo.repo_id, workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(self.target_repo.repo_id, workspace_id) if os.path.isdir(shadow_repository_path): return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_versions" + __table_args__ = (base_table_args,) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -4014,10 +3913,8 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = (base_table_args,) @hybrid_property def reasons(self): @@ -4029,79 +3926,72 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), + Index("notification_type_idx", "type"), base_table_args, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -4133,20 +4023,22 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' - __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - base_table_args + __tablename__ = "user_to_notification" + __table_args__ = (UniqueConstraint("user_id", "notification_id"), base_table_args) + + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) - - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -4154,38 +4046,39 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - base_table_args + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + base_table_args, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -4203,6 +4096,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -4213,8 +4107,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4224,47 +4118,46 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - base_table_args + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + base_table_args, ) - external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): @@ -4312,36 +4205,30 @@ class ExternalIdentity(Base, BaseModel): @classmethod def load_provider_plugin(cls, plugin_id): from rhodecode.authentication.base import loadplugin - _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) + + _plugin_id = "egg:rhodecode-enterprise-ee#{}".format(plugin_id) auth_plugin = loadplugin(_plugin_id) return auth_plugin class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - base_table_args - ) + __tablename__ = "integrations" + __table_args__ = base_table_args - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4349,118 +4236,109 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = base_table_args - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = base_table_args VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules" + __table_args__ = base_table_args - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_pattern(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_pattern(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_pattern(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -4471,37 +4349,37 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - if self.source_branch_pattern.startswith('re:'): + if self.source_branch_pattern.startswith("re:"): source_pattern = self.source_branch_pattern[3:] else: - source_pattern = '^' + glob2re(self.source_branch_pattern) + '$' + source_pattern = "^" + glob2re(self.source_branch_pattern) + "$" source_branch_regex = re.compile(source_pattern) source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - if self.target_branch_pattern.startswith('re:'): + if self.target_branch_pattern.startswith("re:"): target_pattern = self.target_branch_pattern[3:] else: - target_pattern = '^' + glob2re(self.target_branch_pattern) + '$' + target_pattern = "^" + glob2re(self.target_branch_pattern) + "$" target_branch_regex = re.compile(target_pattern) target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False - if self.file_pattern.startswith('re:'): + if self.file_pattern.startswith("re:"): file_pattern = self.file_pattern[3:] else: file_pattern = glob2re(self.file_pattern) @@ -4515,7 +4393,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4523,17 +4401,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -4545,16 +4423,15 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def user_group_vote_rule(self, user_id): - rules = [] if not self.rule_user_groups: return rules @@ -4566,39 +4443,45 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), base_table_args, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -4607,8 +4490,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -4629,8 +4511,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -4648,6 +4529,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -4666,7 +4548,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -4686,16 +4568,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -4707,19 +4588,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -4730,88 +4611,122 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class UserBookmark(Base, BaseModel): - __tablename__ = 'user_bookmarks' + __tablename__ = "user_bookmarks" __table_args__ = ( - UniqueConstraint('user_id', 'bookmark_repo_id'), - UniqueConstraint('user_id', 'bookmark_repo_group_id'), - UniqueConstraint('user_id', 'bookmark_position'), - base_table_args + UniqueConstraint("user_id", "bookmark_repo_id"), + UniqueConstraint("user_id", "bookmark_repo_group_id"), + UniqueConstraint("user_id", "bookmark_position"), + base_table_args, ) - user_bookmark_id = Column("user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user_bookmark_id = Column( + "user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) position = Column("bookmark_position", Integer(), nullable=False) title = Column("bookmark_title", String(255), nullable=True, unique=None, default=None) redirect_url = Column("bookmark_redirect_url", String(10240), nullable=True, unique=None, default=None) created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - bookmark_repo_id = Column("bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) - bookmark_repo_group_id = Column("bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None) + bookmark_repo_id = Column( + "bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + bookmark_repo_group_id = Column( + "bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) user = relationship("User") @@ -4820,88 +4735,93 @@ class UserBookmark(Base, BaseModel): @classmethod def get_by_position_for_user(cls, position, user_id): - return cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .filter(UserBookmark.position == position).scalar() + return cls.query().filter(UserBookmark.user_id == user_id).filter(UserBookmark.position == position).scalar() @classmethod def get_bookmarks_for_user(cls, user_id): - return cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .options(joinedload(UserBookmark.repository)) \ - .options(joinedload(UserBookmark.repository_group)) \ - .order_by(UserBookmark.position.asc()) \ + return ( + cls.query() + .filter(UserBookmark.user_id == user_id) + .options(joinedload(UserBookmark.repository)) + .options(joinedload(UserBookmark.repository_group)) + .order_by(UserBookmark.position.asc()) .all() + ) def __unicode__(self): - return u'' % (self.position, self.redirect_url) + return "" % (self.position, self.redirect_url) class FileStore(Base, BaseModel): - __tablename__ = 'file_store' - __table_args__ = ( - base_table_args - ) + __tablename__ = "file_store" + __table_args__ = base_table_args - file_store_id = Column('file_store_id', Integer(), primary_key=True) - file_uid = Column('file_uid', String(1024), nullable=False) - file_display_name = Column('file_display_name', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), nullable=True) - file_description = Column('file_description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - file_org_name = Column('file_org_name', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=False) + file_store_id = Column("file_store_id", Integer(), primary_key=True) + file_uid = Column("file_uid", String(1024), nullable=False) + file_display_name = Column( + "file_display_name", UnicodeText().with_variant(UnicodeText(2048), "mysql"), nullable=True + ) + file_description = Column( + "file_description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True + ) + file_org_name = Column("file_org_name", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=False) # sha256 hash - file_hash = Column('file_hash', String(512), nullable=False) - file_size = Column('file_size', Integer(), nullable=False) + file_hash = Column("file_hash", String(512), nullable=False) + file_size = Column("file_size", Integer(), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True) - accessed_count = Column('accessed_count', Integer(), default=0) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True) + accessed_count = Column("accessed_count", Integer(), default=0) - enabled = Column('enabled', Boolean(), nullable=False, default=True) + enabled = Column("enabled", Boolean(), nullable=False, default=True) # if repo/repo_group reference is set, check for permissions - check_acl = Column('check_acl', Boolean(), nullable=False, default=True) + check_acl = Column("check_acl", Boolean(), nullable=False, default=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - upload_user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + upload_user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.user_id") # scope limited to user, which requester have access to scope_user_id = Column( - 'scope_user_id', Integer(), ForeignKey('users.user_id'), - nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.scope_user_id') + "scope_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.scope_user_id") # scope limited to user group, which requester have access to scope_user_group_id = Column( - 'scope_user_group_id', Integer(), ForeignKey('users_groups.users_group_id'), - nullable=True, unique=None, default=None) - user_group = relationship('UserGroup', lazy='joined') + "scope_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=True, + unique=None, + default=None, + ) + user_group = relationship("UserGroup", lazy="joined") # scope limited to repo, which requester have access to scope_repo_id = Column( - 'scope_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + "scope_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + repo = relationship("Repository", lazy="joined") # scope limited to repo group, which requester have access to scope_repo_group_id = Column( - 'scope_repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "scope_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") def __repr__(self): - return ''.format(self.file_store_id) + return "".format(self.file_store_id) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_migrate_version" + __table_args__ = (base_table_args,) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) @classmethod def set_version(cls, version): @@ -4914,16 +4834,14 @@ class DbMigrateVersion(Base, BaseModel): class DbSession(Base, BaseModel): - __tablename__ = 'db_session' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_session" + __table_args__ = (base_table_args,) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_18_0_1.py b/rhodecode/lib/dbmigrate/schema/db_4_18_0_1.py index 659d4cc1..e574627e 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_18_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_18_0_1.py @@ -35,14 +35,32 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType) + or_, + and_, + not_, + func, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, +) from sqlalchemy.sql.expression import true, false, case from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -55,20 +73,30 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, sha1_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + sha1_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, + datetime_to_time, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher, validate_and_decrypt_data from rhodecode.lib.encrypt2 import Encryptor -from rhodecode.lib.exceptions import ( - ArtifactMetadataDuplicate, ArtifactMetadataBadValueType) +from rhodecode.lib.exceptions import ArtifactMetadataDuplicate, ArtifactMetadataBadValueType from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -83,10 +111,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -98,8 +126,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -110,7 +138,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -134,18 +162,16 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts base_table_args = { - 'extend_existing': True, - 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', - 'sqlite_autoincrement': True + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, } @@ -158,6 +184,7 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): @@ -165,23 +192,21 @@ class EncryptedTextValue(TypeDecorator): Setter for storing value """ import rhodecode + if not value: return value # protect against double encrypting if values is already encrypted - if value.startswith('enc$aes$') \ - or value.startswith('enc$aes_hmac$') \ - or value.startswith('enc2$'): - raise ValueError('value needs to be in unencrypted format, ' - 'ie. not starting with enc$ or enc2$') + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$") or value.startswith("enc2$"): + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$ or enc2$") - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - if algo == 'aes': - return 'enc$aes_hmac$%s' % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) - elif algo == 'fernet': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + if algo == "aes": + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).encrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) def process_result_value(self, value, dialect): """ @@ -189,17 +214,18 @@ class EncryptedTextValue(TypeDecorator): """ import rhodecode + if not value: return value - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - enc_strict_mode = str2bool(rhodecode.CONFIG.get('rhodecode.encrypted_values.strict') or True) - if algo == 'aes': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) + if algo == "aes": decrypted_data = validate_and_decrypt_data(value, ENCRYPTION_KEY, enc_strict_mode) - elif algo == 'fernet': + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).decrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) return decrypted_data @@ -210,20 +236,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -234,11 +260,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -295,48 +326,47 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = ( - UniqueConstraint('app_settings_name'), - base_table_args - ) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), base_table_args) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -346,14 +376,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -365,7 +394,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -376,40 +405,35 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val @classmethod def get_by_prefix(cls, prefix): - return RhodeCodeSetting.query()\ - .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ - .all() + return RhodeCodeSetting.query().filter(RhodeCodeSetting.app_settings_name.startswith(prefix)).all() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = ( - UniqueConstraint('ui_key'), - base_table_args - ) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), base_table_args) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" HOOKS_BUILTIN = [ HOOK_PRE_PULL, @@ -424,60 +448,41 @@ class RhodeCodeUi(Base, BaseModel): # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - base_table_args + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -487,7 +492,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -507,62 +512,60 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - base_table_args + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - base_table_args + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + base_table_args, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -573,57 +576,67 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all, delete-orphan') + user_log = relationship("UserLog") + user_perms = relationship( + "UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all, delete-orphan" + ) - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all, delete-orphan') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') + repo_to_perm = relationship( + "UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -636,6 +649,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -643,6 +657,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -652,11 +667,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -669,10 +686,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -681,10 +700,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] @property @@ -693,27 +709,23 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -722,34 +734,34 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -762,8 +774,10 @@ class User(Base, BaseModel): else: plain_token_map[token.api_key] = token log.debug( - 'Found %s plain and %s encrypted user tokens to check for authentication', - len(plain_token_map), len(enc_token_map)) + "Found %s plain and %s encrypted user tokens to check for authentication", + len(plain_token_map), + len(enc_token_map), + ) # plain token match comes first match = plain_token_map.get(auth_token) @@ -777,16 +791,18 @@ class User(Base, BaseModel): break if match: - log.debug('Found matching token %s', match) + log.debug("Found matching token %s", match) if match.repo_id: - log.debug('Found scope, checking for scope match of token %s', match) + log.debug("Found scope, checking for scope match of token %s", match) if match.repo_id == scope_repo_id: return True else: log.debug( - 'AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - match.repo, scope_repo_id) + "AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + match.repo, + scope_repo_id, + ) return False else: return True @@ -800,29 +816,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -833,6 +848,7 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -848,44 +864,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -893,7 +906,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -902,8 +914,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -915,9 +926,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -929,6 +939,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -947,13 +958,13 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with %s', kwargs) + log.debug("updated userdata with %s", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -963,13 +974,10 @@ class User(Base, BaseModel): @classmethod def get_first_super_admin(cls): - user = User.query()\ - .filter(User.admin == true()) \ - .order_by(User.user_id.asc()) \ - .first() + user = User.query().filter(User.admin == true()).order_by(User.user_id.asc()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -986,7 +994,7 @@ class User(Base, BaseModel): def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -995,14 +1003,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -1016,97 +1025,89 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - base_table_args + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + base_table_args, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1114,12 +1115,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1131,11 +1133,11 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -1144,10 +1146,10 @@ class UserApiKeys(Base, BaseModel): def _get_scope(self): if self.repo: - return 'Repository: {}'.format(self.repo.repo_name) + return "Repository: {}".format(self.repo.repo_name) if self.repo_group: - return 'RepositoryGroup: {} (recursive)'.format(self.repo_group.group_name) - return 'Global' + return "RepositoryGroup: {} (recursive)".format(self.repo_group.group_name) + return "Global" @property def scope_humanized(self): @@ -1160,25 +1162,20 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' - __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - base_table_args - ) - + __tablename__ = "user_email_map" + __table_args__ = (Index("uem_email_idx", "email"), UniqueConstraint("email"), base_table_args) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1191,23 +1188,20 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' - __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - base_table_args - ) - + __tablename__ = "user_ip_map" + __table_args__ = (UniqueConstraint("user_id", "ip_addr"), base_table_args) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1217,43 +1211,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - base_table_args + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + base_table_args, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1263,41 +1253,47 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "user_logs" + __table_args__ = (base_table_args,) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1308,34 +1304,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "users_groups" + __table_args__ = (base_table_args,) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1350,6 +1350,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1370,29 +1371,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1402,16 +1398,14 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for user groups """ - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: @@ -1435,9 +1429,11 @@ class UserGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1467,29 +1463,30 @@ class UserGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupUserGroupToPerm.query()\ - .filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.user_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.user_group.members] + entry.members = [x.user.get_dict() for x in _user_group.user_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1500,13 +1497,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1514,206 +1511,181 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - base_table_args, + __tablename__ = "users_groups_members" + __table_args__ = (base_table_args,) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field + UniqueConstraint("repository_id", "field_key"), # no-multi field base_table_args, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), + Index("r_repo_name_idx", "repo_name", mysql_length=255), base_table_args, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - archived = Column( - "archived", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + archived = Column("archived", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.source_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.target_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") - artifacts = relationship('FileStore', cascade="all") + artifacts = relationship("FileStore", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1722,16 +1694,17 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: - dummy['source_repo_id'] = self.repo_id + dummy["source_repo_id"] = self.repo_id return json.loads(json.dumps(dummy)) try: @@ -1776,13 +1749,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1814,14 +1786,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True, archived=False): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True, archived=False): q = Repository.query() if not archived: @@ -1842,7 +1812,7 @@ class Repository(Base, BaseModel): @property def repo_uid(self): - return '_{}'.format(self.repo_id) + return "_{}".format(self.repo_id) @property def forks(self): @@ -1871,7 +1841,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1889,8 +1859,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1908,12 +1877,8 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - return CacheKey.query()\ - .filter(CacheKey.cache_args == invalidation_namespace)\ - .order_by(CacheKey.cache_key)\ - .all() + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + return CacheKey.query().filter(CacheKey.cache_args == invalidation_namespace).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -1922,16 +1887,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -1940,10 +1901,8 @@ class Repository(Base, BaseModel): return [] def shadow_repos(self): - shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id) - return [ - x for x in os.listdir(os.path.dirname(self.repo_full_path)) - if x.startswith(shadow_repos_pattern)] + shadow_repos_pattern = ".__shadow_repo_{}".format(self.repo_id) + return [x for x in os.listdir(os.path.dirname(self.repo_full_path)) if x.startswith(shadow_repos_pattern)] def get_new_name(self, repo_name): """ @@ -1960,14 +1919,14 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repositories """ - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: @@ -1993,9 +1952,11 @@ class Repository(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2030,19 +1991,19 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=True): - q = UserGroupRepoToPerm.query()\ - .filter(UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2064,33 +2025,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2138,7 +2097,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2151,53 +2110,52 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @property def last_commit_change(self): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = self.changeset_cache.get('date', empty_date) + date_latest = self.changeset_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2212,9 +2170,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2222,57 +2181,55 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides request = get_current_request() if not uri_tmpl: - if hasattr(request, 'call_context') and hasattr(request.call_context, 'rc_config'): + if hasattr(request, "call_context") and hasattr(request.call_context, "rc_config"): rc_config = request.call_context.rc_config else: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + request=request, uri_tmpl=uri_tmpl, repo_name=self.repo_name, repo_id=self.repo_id, **override + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2282,8 +2239,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2311,14 +2267,14 @@ class Repository(Base, BaseModel): """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) empty = scm_repo is None or scm_repo.is_empty() if not empty: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents", "branch"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents", "branch"]) else: cs_cache = EmptyCommit() @@ -2326,43 +2282,43 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.utcnow() - last_change = cs_cache.get('date') or _default + last_change = cs_cache.get("date") or _default # we check if last update is newer than the new value # if yes, we use the current timestamp instead. Imagine you get # old commit pushed 1y ago, we'd set last update 1y to ago. last_change_timestamp = datetime_to_time(last_change) current_timestamp = datetime_to_time(last_change) if last_change_timestamp > current_timestamp: - cs_cache['date'] = _default + cs_cache["date"] = _default - cs_cache['updated_on'] = time.time() + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache Session().add(self) Session().commit() - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) else: cs_cache = self.changeset_cache - cs_cache['updated_on'] = time.time() + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache Session().add(self) Session().commit() - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2378,8 +2334,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2393,19 +2348,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2425,8 +2375,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2438,18 +2387,18 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - vcs_full_cache = kwargs.pop('vcs_full_cache', None) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + vcs_full_cache = kwargs.pop("vcs_full_cache", None) if vcs_full_cache is not None: # allows override global config full_cache = vcs_full_cache else: - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: - log.debug('Initializing pure cached instance for %s', self.repo_path) + log.debug("Initializing pure cached instance for %s", self.repo_path) return self._get_instance_cached() # cache here is sent to the "vcs server" @@ -2458,10 +2407,9 @@ class Repository(Base, BaseModel): def _get_instance_cached(self): from rhodecode.lib import rc_cache - cache_namespace_uid = f'repo_instance.{self.repo_id}' - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) + cache_namespace_uid = f"repo_instance.{self.repo_id}" + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + region = rc_cache.get_or_create_region("cache_repo_longterm", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) def get_instance_cached(repo_id, context_id, _cache_state_uid): @@ -2471,10 +2419,10 @@ class Repository(Base, BaseModel): # because each thread of gevent needs it's own not shared connection and cache # we also alter `args` so the cache key is individual for every green thread. inv_context_manager = rc_cache.InvalidationContext( - uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, - thread_scoped=True) + uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, thread_scoped=True + ) with inv_context_manager as invalidation_context: - cache_state_uid = invalidation_context.cache_data['cache_state_uid'] + cache_state_uid = invalidation_context.cache_data["cache_state_uid"] args = (self.repo_id, inv_context_manager.cache_key, cache_state_uid) # re-compute and store cache if we get invalidate signal @@ -2483,82 +2431,84 @@ class Repository(Base, BaseModel): else: instance = get_instance_cached(*args) - log.debug('Repo instance fetched in %.4fs', inv_context_manager.compute_time) + log.debug("Repo instance fetched in %.4fs", inv_context_manager.compute_time) return instance def _get_instance(self, cache=True, config=None, repo_state_uid=None): - log.debug('Initializing %s instance `%s` with cache flag set to: %s', - self.repo_type, self.repo_path, cache) + log.debug("Initializing %s instance `%s` with cache flag set to: %s", self.repo_type, self.repo_path, cache) config = config or self._config custom_wire = { - 'cache': cache, # controls the vcs.remote cache - 'repo_state_uid': repo_state_uid + "cache": cache, # controls the vcs.remote cache + "repo_state_uid": repo_state_uid, } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) if repo is not None: repo.count() # cache rebuild return repo def get_shadow_repository_path(self, workspace_id): from rhodecode.lib.vcs.backends.base import BaseRepository - shadow_repo_path = BaseRepository._get_shadow_repository_path( - self.repo_full_path, self.repo_id, workspace_id) + + shadow_repo_path = BaseRepository._get_shadow_repository_path(self.repo_full_path, self.repo_id, workspace_id) return shadow_repo_path def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), + UniqueConstraint("group_name", "group_parent_id"), base_table_args, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) _group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) group_name_hash = Column("repo_group_name_hash", String(1024), nullable=False, unique=False) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', cascade="all, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def group_name(self): @@ -2572,9 +2522,10 @@ class RepoGroup(Base, BaseModel): @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: - dummy['source_repo_id'] = '' + dummy["source_repo_id"] = "" return json.loads(json.dumps(dummy)) try: @@ -2592,7 +2543,7 @@ class RepoGroup(Base, BaseModel): except Exception: log.error(traceback.format_exc()) - @validates('group_parent_id') + @validates("group_parent_id") def validate_group_parent_id(self, key, val): """ Check cycle references for a parent group to self @@ -2605,6 +2556,7 @@ class RepoGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod @@ -2617,11 +2569,12 @@ class RepoGroup(Base, BaseModel): c = str(ord(c)) chars.append(c) - return ''.join(chars) + return "".join(chars) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2632,12 +2585,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2647,14 +2599,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2663,15 +2613,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user) \ - .order_by(cls.group_id.asc()) \ - .first() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).order_by(cls.group_id.asc()).first() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2687,7 +2632,7 @@ class RepoGroup(Base, BaseModel): return q.all() @property - def parents(self, parents_recursion_limit = 10): + def parents(self, parents_recursion_limit=10): groups = [] if self.parent_group is None: return groups @@ -2696,14 +2641,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2711,13 +2659,14 @@ class RepoGroup(Base, BaseModel): @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @property def last_commit_change(self): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = self.changeset_cache.get('date', empty_date) + date_latest = self.changeset_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2745,9 +2694,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2807,8 +2754,7 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def update_commit_cache(self, config=None): @@ -2831,7 +2777,6 @@ class RepoGroup(Base, BaseModel): all_entries = [] def _get_members(root_gr, pos=0): - for repo in root_gr.repositories: all_entries[root_gr].append(repo) @@ -2842,38 +2787,35 @@ class RepoGroup(Base, BaseModel): children_groups = root_gr.children.all() if children_groups: for cnt, gr in enumerate(children_groups, 1): - _get_members(gr, pos=pos+cnt) + _get_members(gr, pos=pos + cnt) _get_members(root_gr=self) return all_entries empty_date = datetime.datetime.fromtimestamp(0) for repo_group, repos in repo_groups_and_repos().items(): - latest_repo_cs_cache = {} for repo in repos: repo_cs_cache = repo.changeset_cache - date_latest = latest_repo_cs_cache.get('date', empty_date) - date_current = repo_cs_cache.get('date', empty_date) + date_latest = latest_repo_cs_cache.get("date", empty_date) + date_current = repo_cs_cache.get("date", empty_date) current_timestamp = datetime_to_time(parse_datetime(date_latest)) if current_timestamp < datetime_to_time(parse_datetime(date_current)): latest_repo_cs_cache = repo_cs_cache - latest_repo_cs_cache['source_repo_id'] = repo.repo_id + latest_repo_cs_cache["source_repo_id"] = repo.repo_id - latest_repo_cs_cache['updated_on'] = time.time() + latest_repo_cs_cache["updated_on"] = time.time() repo_group.changeset_cache = latest_repo_cs_cache Session().add(repo_group) Session().commit() - log.debug('updated repo group %s with new commit cache %s', - repo_group.group_name, latest_repo_cs_cache) + log.debug("updated repo group %s with new commit cache %s", repo_group.group_name, latest_repo_cs_cache) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repository groups """ - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: @@ -2897,9 +2839,11 @@ class RepoGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2929,19 +2873,19 @@ class RepoGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupRepoGroupToPerm.query()\ - .filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2954,12 +2898,12 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data @@ -2967,124 +2911,112 @@ class RepoGroup(Base, BaseModel): # Since we transformed `group_name` to a hybrid property, we need to # keep compatibility with the code which uses `group_name` field. result = super(RepoGroup, self).get_dict() - result['group_name'] = result.pop('_group_name', None) + result["group_name"] = result.pop("_group_name", None) return result class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), + Index("p_perm_name_idx", "permission_name"), base_table_args, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch, for backward compat we need same value as before so forced pushed - 'branch.push_force', + "branch.push_force", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -3092,9 +3024,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -3102,24 +3032,26 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms(cls, user_id, repo_id=None): - q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ - .join( - Permission, - UserToRepoBranchPermission.permission_id == Permission.permission_id) \ - .join( - UserRepoToPerm, - UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ + q = ( + Session() + .query(UserToRepoBranchPermission, UserRepoToPerm, Permission) + .join(Permission, UserToRepoBranchPermission.permission_id == Permission.permission_id) + .join(UserRepoToPerm, UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) @@ -3127,46 +3059,33 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ - .join( - Permission, - UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ + q = ( + Session() + .query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) + .join(Permission, UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) .join( UserGroupRepoToPerm, - UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id, + ) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) @@ -3174,102 +3093,81 @@ class Permission(Base, BaseModel): @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserRepoGroupToPerm.permission_id == Permission.permission_id)\ - .join( - RepoGroup, - UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - base_table_args - ) + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id", "permission_id"), base_table_args) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -3281,24 +3179,27 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - base_table_args + __tablename__ = "user_user_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "user_group_id", "permission_id"), base_table_args) + + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -3310,43 +3211,52 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - base_table_args - ) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), base_table_args) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - base_table_args + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), base_table_args) + + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') - user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") + user_group_branch_perms = relationship("UserGroupToRepoBranchPermission", cascade="all") @classmethod def create(cls, users_group, repository, permission): @@ -3358,25 +3268,42 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - base_table_args + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + base_table_args, ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None + ) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3388,39 +3315,54 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - base_table_args + UniqueConstraint( + "users_group_id", + "permission_id", + ), + base_table_args, ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - base_table_args + __tablename__ = "user_repo_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "group_id", "permission_id"), base_table_args) + + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3433,20 +3375,28 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - base_table_args + __tablename__ = "users_group_repo_group_to_perm" + __table_args__ = (UniqueConstraint("users_group_id", "group_id"), base_table_args) + + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3458,43 +3408,51 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - base_table_args - ) + __tablename__ = "statistics" + __table_args__ = base_table_args stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - base_table_args + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + base_table_args, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3502,18 +3460,18 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), base_table_args, ) - CACHE_TYPE_FEED = 'FEED' + CACHE_TYPE_FEED = "FEED" # namespaces used to register process/thread aware caches - REPO_INVALIDATION_NAMESPACE = 'repo_cache:{repo_id}' - SETTINGS_INVALIDATION_NAMESPACE = 'system_settings' + REPO_INVALIDATION_NAMESPACE = "repo_cache:{repo_id}" + SETTINGS_INVALIDATION_NAMESPACE = "system_settings" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) @@ -3521,7 +3479,7 @@ class CacheKey(Base, BaseModel): cache_state_uid = Column("cache_state_uid", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args='', cache_state_uid=None): + def __init__(self, cache_key, cache_args="", cache_state_uid=None): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False @@ -3529,9 +3487,7 @@ class CacheKey(Base, BaseModel): self.cache_state_uid = cache_state_uid or self.generate_new_state_uid() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3581,19 +3537,14 @@ class CacheKey(Base, BaseModel): qry = Session().query(cls).filter(cls.cache_args == cache_uid) if delete: qry.delete() - log.debug('cache objects deleted for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects deleted for cache args %s", safe_str(cache_uid)) else: - qry.update({"cache_active": False, - "cache_state_uid": cls.generate_new_state_uid()}) - log.debug('cache objects marked as invalid for cache args %s', - safe_str(cache_uid)) + qry.update({"cache_active": False, "cache_state_uid": cls.generate_new_state_uid()}) + log.debug("cache objects marked as invalid for cache args %s", safe_str(cache_uid)) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for cache args %s', - safe_str(cache_uid)) + log.exception("Cache key invalidation failed for cache args %s", safe_str(cache_uid)) Session().rollback() @classmethod @@ -3605,49 +3556,51 @@ class CacheKey(Base, BaseModel): @classmethod def get_namespace_map(cls, namespace): - return { - x.cache_key: x - for x in cls.query().filter(cls.cache_args == namespace)} + return {x.cache_key: x for x in cls.query().filter(cls.cache_args == namespace)} class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), + Index("cc_revision_idx", "revision"), base_table_args, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') - resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, back_populates="resolved_by") + resolved_by = relationship("ChangesetComment", back_populates="resolved_comment") - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3658,8 +3611,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3670,7 +3622,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3706,27 +3658,26 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on, - 'comment_resolved_by': self.resolved + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, + "comment_resolved_by": self.resolved, } return data @@ -3737,18 +3688,18 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - base_table_args + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + base_table_args, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3757,26 +3708,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3789,8 +3737,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3813,8 +3761,7 @@ class _SetState(object): self._current_state = None def __enter__(self): - log.debug('StateLock: entering set state context, setting state to: `%s`', - self._pr_state) + log.debug("StateLock: entering set state context, setting state to: `%s`", self._pr_state) self.set_pr_state(self._pr_state) return self @@ -3824,8 +3771,8 @@ class _SetState(object): return None self.set_pr_state(self._org_state) - log.debug('StateLock: exiting set state context, setting state to: `%s`', - self._org_state) + log.debug("StateLock: exiting set state context, setting state to: `%s`", self._org_state) + @property def state(self): return self._current_state @@ -3837,60 +3784,50 @@ class _SetState(object): Session().commit() self._current_state = pr_state except Exception: - log.exception('Failed to set PullRequest %s state to %s', self._pr, pr_state) + log.exception("Failed to set PullRequest %s state to %s", self._pr, pr_state) raise + class _PullRequestBase(BaseModel): """ Common attributes of pull request and version entries. """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" # available states - STATE_CREATING = u'creating' - STATE_UPDATING = u'updating' - STATE_MERGING = u'merging' - STATE_CREATED = u'created' + STATE_CREATING = "creating" + STATE_UPDATING = "updating" + STATE_MERGING = "merging" + STATE_CREATED = "created" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) - description_renderer = Column('description_renderer', Unicode(64), nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + description_renderer = Column("description_renderer", Unicode(64), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) pull_request_state = Column("pull_request_state", String(255), nullable=True) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _source_ref = Column('org_ref', Unicode(255), nullable=False) + _source_ref = Column("org_ref", Unicode(255), nullable=False) @hybrid_property def source_ref(self): @@ -3898,13 +3835,12 @@ class _PullRequestBase(BaseModel): @source_ref.setter def source_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._source_ref = safe_str(val) - _target_ref = Column('other_ref', Unicode(255), nullable=False) + _target_ref = Column("other_ref", Unicode(255), nullable=False) @hybrid_property def target_ref(self): @@ -3912,33 +3848,28 @@ class _PullRequestBase(BaseModel): @target_ref.setter def target_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._target_ref = safe_str(val) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -3947,15 +3878,16 @@ class _PullRequestBase(BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = u':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -3967,13 +3899,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3981,9 +3911,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -4004,7 +3932,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -4016,7 +3944,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -4027,63 +3955,57 @@ class _PullRequestBase(BaseModel): if with_merge_state: merge_status = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status[0], - 'message': safe_str(merge_status[1]), + "status": merge_status[0], + "message": safe_str(merge_status[1]), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'state': pull_request.pull_request_state, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "state": pull_request.pull_request_state, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data @@ -4104,34 +4026,24 @@ class _PullRequestBase(BaseModel): class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_requests" + __table_args__ = (base_table_args,) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete-orphan") - statuses = relationship('ChangesetStatus', - cascade="all, delete-orphan") - comments = relationship('ChangesetComment', - cascade="all, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -4142,7 +4054,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -4150,35 +4062,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data(with_merge_state=False)) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -4196,20 +4103,23 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): @@ -4221,23 +4131,18 @@ class PullRequest(Base, _PullRequestBase): class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_versions" + __table_args__ = (base_table_args,) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -4259,10 +4164,8 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = (base_table_args,) @hybrid_property def reasons(self): @@ -4274,79 +4177,72 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), + Index("notification_type_idx", "type"), base_table_args, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -4378,20 +4274,22 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' - __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - base_table_args + __tablename__ = "user_to_notification" + __table_args__ = (UniqueConstraint("user_id", "notification_id"), base_table_args) + + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) - - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -4399,38 +4297,39 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - base_table_args + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + base_table_args, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -4448,6 +4347,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -4458,8 +4358,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4469,24 +4369,24 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): @@ -4496,27 +4396,26 @@ class Gist(Base, BaseModel): :param kwargs: """ from rhodecode.model.gist import GistModel + full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False, - _vcs_alias=GistModel.vcs_backend) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False, _vcs_alias=GistModel.vcs_backend) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - base_table_args + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + base_table_args, ) - external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): @@ -4564,36 +4463,30 @@ class ExternalIdentity(Base, BaseModel): @classmethod def load_provider_plugin(cls, plugin_id): from rhodecode.authentication.base import loadplugin - _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) + + _plugin_id = "egg:rhodecode-enterprise-ee#{}".format(plugin_id) auth_plugin = loadplugin(_plugin_id) return auth_plugin class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - base_table_args - ) + __tablename__ = "integrations" + __table_args__ = base_table_args - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4601,118 +4494,109 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = base_table_args - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = base_table_args VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules" + __table_args__ = base_table_args - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_pattern(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_pattern(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_pattern(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -4723,37 +4607,37 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - if self.source_branch_pattern.startswith('re:'): + if self.source_branch_pattern.startswith("re:"): source_pattern = self.source_branch_pattern[3:] else: - source_pattern = '^' + glob2re(self.source_branch_pattern) + '$' + source_pattern = "^" + glob2re(self.source_branch_pattern) + "$" source_branch_regex = re.compile(source_pattern) source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - if self.target_branch_pattern.startswith('re:'): + if self.target_branch_pattern.startswith("re:"): target_pattern = self.target_branch_pattern[3:] else: - target_pattern = '^' + glob2re(self.target_branch_pattern) + '$' + target_pattern = "^" + glob2re(self.target_branch_pattern) + "$" target_branch_regex = re.compile(target_pattern) target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False - if self.file_pattern.startswith('re:'): + if self.file_pattern.startswith("re:"): file_pattern = self.file_pattern[3:] else: file_pattern = glob2re(self.file_pattern) @@ -4767,7 +4651,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4775,17 +4659,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -4797,16 +4681,15 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def user_group_vote_rule(self, user_id): - rules = [] if not self.rule_user_groups: return rules @@ -4818,39 +4701,45 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), base_table_args, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -4859,8 +4748,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -4881,8 +4769,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -4900,6 +4787,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -4918,7 +4806,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -4938,16 +4826,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -4959,19 +4846,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -4982,86 +4869,112 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class UserBookmark(Base, BaseModel): - __tablename__ = 'user_bookmarks' + __tablename__ = "user_bookmarks" __table_args__ = ( - UniqueConstraint('user_id', 'bookmark_repo_id'), - UniqueConstraint('user_id', 'bookmark_repo_group_id'), - UniqueConstraint('user_id', 'bookmark_position'), - base_table_args + UniqueConstraint("user_id", "bookmark_repo_id"), + UniqueConstraint("user_id", "bookmark_repo_group_id"), + UniqueConstraint("user_id", "bookmark_position"), + base_table_args, ) - user_bookmark_id = Column("user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user_bookmark_id = Column( + "user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) position = Column("bookmark_position", Integer(), nullable=False) title = Column("bookmark_title", String(255), nullable=True, unique=None, default=None) redirect_url = Column("bookmark_redirect_url", String(10240), nullable=True, unique=None, default=None) created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - bookmark_repo_id = Column("bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) - bookmark_repo_group_id = Column("bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None) + bookmark_repo_id = Column( + "bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + bookmark_repo_group_id = Column( + "bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) user = relationship("User") @@ -5070,89 +4983,108 @@ class UserBookmark(Base, BaseModel): @classmethod def get_by_position_for_user(cls, position, user_id): - return cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .filter(UserBookmark.position == position).scalar() + return cls.query().filter(UserBookmark.user_id == user_id).filter(UserBookmark.position == position).scalar() @classmethod def get_bookmarks_for_user(cls, user_id): - return cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .options(joinedload(UserBookmark.repository)) \ - .options(joinedload(UserBookmark.repository_group)) \ - .order_by(UserBookmark.position.asc()) \ + return ( + cls.query() + .filter(UserBookmark.user_id == user_id) + .options(joinedload(UserBookmark.repository)) + .options(joinedload(UserBookmark.repository_group)) + .order_by(UserBookmark.position.asc()) .all() + ) def __unicode__(self): - return u'' % (self.position, self.redirect_url) + return "" % (self.position, self.redirect_url) class FileStore(Base, BaseModel): - __tablename__ = 'file_store' - __table_args__ = ( - base_table_args - ) + __tablename__ = "file_store" + __table_args__ = base_table_args - file_store_id = Column('file_store_id', Integer(), primary_key=True) - file_uid = Column('file_uid', String(1024), nullable=False) - file_display_name = Column('file_display_name', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), nullable=True) - file_description = Column('file_description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - file_org_name = Column('file_org_name', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=False) + file_store_id = Column("file_store_id", Integer(), primary_key=True) + file_uid = Column("file_uid", String(1024), nullable=False) + file_display_name = Column( + "file_display_name", UnicodeText().with_variant(UnicodeText(2048), "mysql"), nullable=True + ) + file_description = Column( + "file_description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True + ) + file_org_name = Column("file_org_name", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=False) # sha256 hash - file_hash = Column('file_hash', String(512), nullable=False) - file_size = Column('file_size', Integer(), nullable=False) + file_hash = Column("file_hash", String(512), nullable=False) + file_size = Column("file_size", Integer(), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True) - accessed_count = Column('accessed_count', Integer(), default=0) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True) + accessed_count = Column("accessed_count", Integer(), default=0) - enabled = Column('enabled', Boolean(), nullable=False, default=True) + enabled = Column("enabled", Boolean(), nullable=False, default=True) # if repo/repo_group reference is set, check for permissions - check_acl = Column('check_acl', Boolean(), nullable=False, default=True) + check_acl = Column("check_acl", Boolean(), nullable=False, default=True) # hidden defines an attachment that should be hidden from showing in artifact listing - hidden = Column('hidden', Boolean(), nullable=False, default=False) + hidden = Column("hidden", Boolean(), nullable=False, default=False) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - upload_user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + upload_user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.user_id") - file_metadata = relationship('FileStoreMetadata', lazy='joined') + file_metadata = relationship("FileStoreMetadata", lazy="joined") # scope limited to user, which requester have access to scope_user_id = Column( - 'scope_user_id', Integer(), ForeignKey('users.user_id'), - nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.scope_user_id') + "scope_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.scope_user_id") # scope limited to user group, which requester have access to scope_user_group_id = Column( - 'scope_user_group_id', Integer(), ForeignKey('users_groups.users_group_id'), - nullable=True, unique=None, default=None) - user_group = relationship('UserGroup', lazy='joined') + "scope_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=True, + unique=None, + default=None, + ) + user_group = relationship("UserGroup", lazy="joined") # scope limited to repo, which requester have access to scope_repo_id = Column( - 'scope_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + "scope_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + repo = relationship("Repository", lazy="joined") # scope limited to repo group, which requester have access to scope_repo_group_id = Column( - 'scope_repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "scope_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @classmethod def get_by_store_uid(cls, file_store_uid): return FileStore.query().filter(FileStore.file_uid == file_store_uid).scalar() @classmethod - def create(cls, file_uid, filename, file_hash, file_size, file_display_name='', - file_description='', enabled=True, hidden=False, check_acl=True, - user_id=None, scope_user_id=None, scope_repo_id=None, scope_repo_group_id=None): - + def create( + cls, + file_uid, + filename, + file_hash, + file_size, + file_display_name="", + file_description="", + enabled=True, + hidden=False, + check_acl=True, + user_id=None, + scope_user_id=None, + scope_repo_id=None, + scope_repo_group_id=None, + ): store_entry = FileStore() store_entry.file_uid = file_uid store_entry.file_display_name = file_display_name @@ -5179,14 +5111,16 @@ class FileStore(Base, BaseModel): return for section, key, value, value_type in args: - has_key = FileStoreMetadata().query() \ - .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) \ - .filter(FileStoreMetadata.file_store_meta_section == section) \ - .filter(FileStoreMetadata.file_store_meta_key == key) \ + has_key = ( + FileStoreMetadata() + .query() + .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) + .filter(FileStoreMetadata.file_store_meta_section == section) + .filter(FileStoreMetadata.file_store_meta_key == key) .scalar() + ) if has_key: - msg = 'key `{}` already defined under section `{}` for this file.'\ - .format(key, section) + msg = "key `{}` already defined under section `{}` for this file.".format(key, section) raise ArtifactMetadataDuplicate(msg, err_section=section, err_key=key) # NOTE(marcink): raises ArtifactMetadataBadValueType @@ -5206,69 +5140,82 @@ class FileStore(Base, BaseModel): Session().commit() except IntegrityError: Session().rollback() - raise ArtifactMetadataDuplicate('Duplicate section/key found for this file.') + raise ArtifactMetadataDuplicate("Duplicate section/key found for this file.") @classmethod def bump_access_counter(cls, file_uid, commit=True): - FileStore().query()\ - .filter(FileStore.file_uid == file_uid)\ - .update({FileStore.accessed_count: (FileStore.accessed_count + 1), - FileStore.accessed_on: datetime.datetime.now()}) + FileStore().query().filter(FileStore.file_uid == file_uid).update( + {FileStore.accessed_count: (FileStore.accessed_count + 1), FileStore.accessed_on: datetime.datetime.now()} + ) if commit: Session().commit() def __repr__(self): - return ''.format(self.file_store_id) + return "".format(self.file_store_id) class FileStoreMetadata(Base, BaseModel): - __tablename__ = 'file_store_metadata' + __tablename__ = "file_store_metadata" __table_args__ = ( - UniqueConstraint('file_store_id', 'file_store_meta_section_hash', 'file_store_meta_key_hash'), - Index('file_store_meta_section_idx', 'file_store_meta_section', mysql_length=255), - Index('file_store_meta_key_idx', 'file_store_meta_key', mysql_length=255), - base_table_args + UniqueConstraint("file_store_id", "file_store_meta_section_hash", "file_store_meta_key_hash"), + Index("file_store_meta_section_idx", "file_store_meta_section", mysql_length=255), + Index("file_store_meta_key_idx", "file_store_meta_key", mysql_length=255), + base_table_args, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } file_store_meta_id = Column( - "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) + "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) _file_store_meta_section = Column( - "file_store_meta_section", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_section", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_section_hash = Column( - "file_store_meta_section_hash", String(255), - nullable=True, unique=None, default=None) + "file_store_meta_section_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_key = Column( - "file_store_meta_key", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_key", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_key_hash = Column( - "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None) + "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_value = Column( - "file_store_meta_value", UnicodeText().with_variant(UnicodeText(20480), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_value", + UnicodeText().with_variant(UnicodeText(20480), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_value_type = Column( - "file_store_meta_value_type", String(255), nullable=True, unique=None, - default='unicode') + "file_store_meta_value_type", String(255), nullable=True, unique=None, default="unicode" + ) file_store_id = Column( - 'file_store_id', Integer(), ForeignKey('file_store.file_store_id'), - nullable=True, unique=None, default=None) + "file_store_id", Integer(), ForeignKey("file_store.file_store_id"), nullable=True, unique=None, default=None + ) - file_store = relationship('FileStore', lazy='joined') + file_store = relationship("FileStore", lazy="joined") @classmethod def valid_value_type(cls, value): - if value.split('.')[0] not in cls.SETTINGS_TYPES: + if value.split(".")[0] not in cls.SETTINGS_TYPES: raise ArtifactMetadataBadValueType( - 'value_type must be one of %s got %s' % (cls.SETTINGS_TYPES.keys(), value)) + "value_type must be one of %s got %s" % (cls.SETTINGS_TYPES.keys(), value) + ) @hybrid_property def file_store_meta_section(self): @@ -5294,13 +5241,13 @@ class FileStoreMetadata(Base, BaseModel): if self._file_store_meta_value_type: # e.g unicode.encrypted == unicode - _type = self._file_store_meta_value_type.split('.')[0] + _type = self._file_store_meta_value_type.split(".")[0] # decode the encrypted value if it's encrypted field type - if '.encrypted' in self._file_store_meta_value_type: + if ".encrypted" in self._file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_result_value(val, None)) # do final type conversion - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] val = converter(val) return val @@ -5309,7 +5256,7 @@ class FileStoreMetadata(Base, BaseModel): def file_store_meta_value(self, val): val = safe_str(val) # encode the encrypted value - if '.encrypted' in self.file_store_meta_value_type: + if ".encrypted" in self.file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._file_store_meta_value = val @@ -5326,28 +5273,30 @@ class FileStoreMetadata(Base, BaseModel): def __json__(self): data = { - 'artifact': self.file_store.file_uid, - 'section': self.file_store_meta_section, - 'key': self.file_store_meta_key, - 'value': self.file_store_meta_value, + "artifact": self.file_store.file_uid, + "section": self.file_store_meta_section, + "key": self.file_store_meta_key, + "value": self.file_store_meta_value, } return data def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.file_store_meta_section, - self.file_store_meta_key, self.file_store_meta_value) + return "<%s[%s]%s=>%s]>" % ( + self.__class__.__name__, + self.file_store_meta_section, + self.file_store_meta_key, + self.file_store_meta_value, + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_migrate_version" + __table_args__ = (base_table_args,) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) @classmethod def set_version(cls, version): @@ -5360,16 +5309,14 @@ class DbMigrateVersion(Base, BaseModel): class DbSession(Base, BaseModel): - __tablename__ = 'db_session' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_session" + __table_args__ = (base_table_args,) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_19_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_19_0_0.py index 04f3dae4..cf4c900b 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_19_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_19_0_0.py @@ -35,14 +35,34 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, cast, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType, BigInteger) + or_, + and_, + not_, + func, + cast, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, + BigInteger, +) from sqlalchemy.sql.expression import true, false, case from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -55,20 +75,30 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance, VCSError from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, sha1_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + sha1_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, + datetime_to_time, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher, validate_and_decrypt_data from rhodecode.lib.encrypt2 import Encryptor -from rhodecode.lib.exceptions import ( - ArtifactMetadataDuplicate, ArtifactMetadataBadValueType) +from rhodecode.lib.exceptions import ArtifactMetadataDuplicate, ArtifactMetadataBadValueType from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -83,10 +113,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -98,8 +128,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -110,7 +140,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -134,18 +164,16 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts base_table_args = { - 'extend_existing': True, - 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', - 'sqlite_autoincrement': True + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, } @@ -158,6 +186,7 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): @@ -165,23 +194,21 @@ class EncryptedTextValue(TypeDecorator): Setter for storing value """ import rhodecode + if not value: return value # protect against double encrypting if values is already encrypted - if value.startswith('enc$aes$') \ - or value.startswith('enc$aes_hmac$') \ - or value.startswith('enc2$'): - raise ValueError('value needs to be in unencrypted format, ' - 'ie. not starting with enc$ or enc2$') + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$") or value.startswith("enc2$"): + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$ or enc2$") - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - if algo == 'aes': - return 'enc$aes_hmac$%s' % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) - elif algo == 'fernet': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + if algo == "aes": + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).encrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) def process_result_value(self, value, dialect): """ @@ -189,17 +216,18 @@ class EncryptedTextValue(TypeDecorator): """ import rhodecode + if not value: return value - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - enc_strict_mode = str2bool(rhodecode.CONFIG.get('rhodecode.encrypted_values.strict') or True) - if algo == 'aes': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) + if algo == "aes": decrypted_data = validate_and_decrypt_data(value, ENCRYPTION_KEY, enc_strict_mode) - elif algo == 'fernet': + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).decrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) return decrypted_data @@ -210,20 +238,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -234,11 +262,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -295,48 +328,47 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = ( - UniqueConstraint('app_settings_name'), - base_table_args - ) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), base_table_args) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -346,14 +378,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -365,7 +396,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -376,40 +407,35 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val @classmethod def get_by_prefix(cls, prefix): - return RhodeCodeSetting.query()\ - .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ - .all() + return RhodeCodeSetting.query().filter(RhodeCodeSetting.app_settings_name.startswith(prefix)).all() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = ( - UniqueConstraint('ui_key'), - base_table_args - ) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), base_table_args) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" HOOKS_BUILTIN = [ HOOK_PRE_PULL, @@ -424,60 +450,41 @@ class RhodeCodeUi(Base, BaseModel): # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - base_table_args + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -487,7 +494,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -507,62 +514,60 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - base_table_args + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - base_table_args + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + base_table_args, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -573,64 +578,74 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all, delete-orphan') + user_log = relationship("UserLog") + user_perms = relationship( + "UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all, delete-orphan" + ) - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all, delete-orphan') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') + repo_to_perm = relationship( + "UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities external_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") # artifacts owned - artifacts = relationship('FileStore', primaryjoin='FileStore.user_id==User.user_id') + artifacts = relationship("FileStore", primaryjoin="FileStore.user_id==User.user_id") # no cascade, set NULL - scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_user_id==User.user_id') + scope_artifacts = relationship("FileStore", primaryjoin="FileStore.scope_user_id==User.user_id") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -643,6 +658,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -650,6 +666,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -659,11 +676,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -676,10 +695,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -688,20 +709,13 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] def emails_cached(self): - emails = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) + emails = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()) - emails = emails.options( - FromCache("sql_cache_short", "get_user_{}_emails".format(self.user_id)) - ) + emails = emails.options(FromCache("sql_cache_short", "get_user_{}_emails".format(self.user_id))) return [self.email] + [x.email for x in emails] @@ -711,44 +725,43 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @LazyProperty def artifact_token(self): return self.get_artifact_token() def get_artifact_token(self, cache=True): - artifacts_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ + artifacts_tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == self) .filter(UserApiKeys.role == UserApiKeys.ROLE_ARTIFACT_DOWNLOAD) + ) if cache: artifacts_tokens = artifacts_tokens.options( - FromCache("sql_cache_short", "get_user_artifact_token_%s" % self.user_id)) + FromCache("sql_cache_short", "get_user_artifact_token_%s" % self.user_id) + ) artifacts_tokens = artifacts_tokens.all() if artifacts_tokens: return artifacts_tokens[0].api_key - return 'NO_ARTIFACT_TOKEN_AVAILABLE' + return "NO_ARTIFACT_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -757,34 +770,34 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -797,8 +810,10 @@ class User(Base, BaseModel): else: plain_token_map[token.api_key] = token log.debug( - 'Found %s plain and %s encrypted tokens to check for authentication for this user', - len(plain_token_map), len(enc_token_map)) + "Found %s plain and %s encrypted tokens to check for authentication for this user", + len(plain_token_map), + len(enc_token_map), + ) # plain token match comes first match = plain_token_map.get(auth_token) @@ -812,16 +827,18 @@ class User(Base, BaseModel): break if match: - log.debug('Found matching token %s', match) + log.debug("Found matching token %s", match) if match.repo_id: - log.debug('Found scope, checking for scope match of token %s', match) + log.debug("Found scope, checking for scope match of token %s", match) if match.repo_id == scope_repo_id: return True else: log.debug( - 'AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - match.repo, scope_repo_id) + "AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + match.repo, + scope_repo_id, + ) return False else: return True @@ -835,29 +852,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -865,13 +881,14 @@ class User(Base, BaseModel): @property def language(self): - return self.user_data.get('language') + return self.user_data.get("language") def AuthUser(self, **kwargs): """ Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -887,44 +904,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -932,7 +946,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -941,8 +954,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -954,9 +966,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -968,6 +979,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -986,13 +998,13 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with %s', kwargs) + log.debug("updated userdata with %s", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -1002,13 +1014,10 @@ class User(Base, BaseModel): @classmethod def get_first_super_admin(cls): - user = User.query()\ - .filter(User.admin == true()) \ - .order_by(User.user_id.asc()) \ - .first() + user = User.query().filter(User.admin == true()).order_by(User.user_id.asc()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -1036,7 +1045,7 @@ class User(Base, BaseModel): def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -1045,14 +1054,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -1066,99 +1076,91 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'description': user.description, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "description": user.description, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - base_table_args + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + base_table_args, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_ARTIFACT_DOWNLOAD = 'role_artifact_download' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_ARTIFACT_DOWNLOAD = "role_artifact_download" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED, ROLE_ARTIFACT_DOWNLOAD] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1166,12 +1168,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1183,12 +1186,12 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), - cls.ROLE_ARTIFACT_DOWNLOAD: _('artifacts downloads'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), + cls.ROLE_ARTIFACT_DOWNLOAD: _("artifacts downloads"), }.get(role, role) @property @@ -1197,10 +1200,10 @@ class UserApiKeys(Base, BaseModel): def _get_scope(self): if self.repo: - return 'Repository: {}'.format(self.repo.repo_name) + return "Repository: {}".format(self.repo.repo_name) if self.repo_group: - return 'RepositoryGroup: {} (recursive)'.format(self.repo_group.group_name) - return 'Global' + return "RepositoryGroup: {} (recursive)".format(self.repo_group.group_name) + return "Global" @property def scope_humanized(self): @@ -1213,25 +1216,20 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' - __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - base_table_args - ) - + __tablename__ = "user_email_map" + __table_args__ = (Index("uem_email_idx", "email"), UniqueConstraint("email"), base_table_args) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1244,23 +1242,20 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' - __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - base_table_args - ) - + __tablename__ = "user_ip_map" + __table_args__ = (UniqueConstraint("user_id", "ip_addr"), base_table_args) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1270,43 +1265,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - base_table_args + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + base_table_args, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1316,41 +1307,47 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "user_logs" + __table_args__ = (base_table_args,) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1361,34 +1358,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "users_groups" + __table_args__ = (base_table_args,) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1403,6 +1404,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1423,29 +1425,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1455,16 +1452,14 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for user groups """ - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: @@ -1488,9 +1483,11 @@ class UserGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1520,29 +1517,30 @@ class UserGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupUserGroupToPerm.query()\ - .filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.user_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.user_group.members] + entry.members = [x.user.get_dict() for x in _user_group.user_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1553,13 +1551,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1567,207 +1565,182 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - base_table_args, + __tablename__ = "users_groups_members" + __table_args__ = (base_table_args,) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field + UniqueConstraint("repository_id", "field_key"), # no-multi field base_table_args, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), + Index("r_repo_name_idx", "repo_name", mysql_length=255), base_table_args, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - archived = Column( - "archived", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + archived = Column("archived", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.source_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.target_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") # no cascade, set NULL - artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_id==Repository.repo_id') + artifacts = relationship("FileStore", primaryjoin="FileStore.scope_repo_id==Repository.repo_id") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1776,16 +1749,17 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @classmethod def _load_changeset_cache(cls, repo_id, changeset_cache_raw): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not changeset_cache_raw: - dummy['source_repo_id'] = repo_id + dummy["source_repo_id"] = repo_id return json.loads(json.dumps(dummy)) try: @@ -1834,13 +1808,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1872,14 +1845,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True, archived=False): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True, archived=False): q = Repository.query() if not archived: @@ -1900,7 +1871,7 @@ class Repository(Base, BaseModel): @property def repo_uid(self): - return '_{}'.format(self.repo_id) + return "_{}".format(self.repo_id) @property def forks(self): @@ -1929,7 +1900,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1947,8 +1918,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1966,12 +1936,8 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - return CacheKey.query()\ - .filter(CacheKey.cache_args == invalidation_namespace)\ - .order_by(CacheKey.cache_key)\ - .all() + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + return CacheKey.query().filter(CacheKey.cache_args == invalidation_namespace).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -1980,16 +1946,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -1998,10 +1960,8 @@ class Repository(Base, BaseModel): return [] def shadow_repos(self): - shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id) - return [ - x for x in os.listdir(os.path.dirname(self.repo_full_path)) - if x.startswith(shadow_repos_pattern)] + shadow_repos_pattern = ".__shadow_repo_{}".format(self.repo_id) + return [x for x in os.listdir(os.path.dirname(self.repo_full_path)) if x.startswith(shadow_repos_pattern)] def get_new_name(self, repo_name): """ @@ -2018,14 +1978,14 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repositories """ - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: @@ -2051,9 +2011,11 @@ class Repository(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2088,19 +2050,19 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=True): - q = UserGroupRepoToPerm.query()\ - .filter(UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2122,33 +2084,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2196,7 +2156,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2209,53 +2169,52 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @classmethod def _load_commit_change(cls, last_commit_cache): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = last_commit_cache.get('date', empty_date) + date_latest = last_commit_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2274,9 +2233,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2284,62 +2244,64 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides request = get_current_request() if not uri_tmpl: - if hasattr(request, 'call_context') and hasattr(request.call_context, 'rc_config'): + if hasattr(request, "call_context") and hasattr(request.call_context, "rc_config"): rc_config = request.call_context.rc_config else: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, - repo_type=self.repo_type, - **override) + return get_clone_url( + request=request, + uri_tmpl=uri_tmpl, + repo_name=self.repo_name, + repo_id=self.repo_id, + repo_type=self.repo_type, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, maybe_unreachable=False): return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load, - maybe_unreachable=maybe_unreachable) + self.scm_instance(), commit_id, commit_idx, pre_load=pre_load, maybe_unreachable=maybe_unreachable + ) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2349,8 +2311,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2363,7 +2324,7 @@ class Repository(Base, BaseModel): return commit def flush_commit_cache(self): - self.update_commit_cache(cs_cache={'raw_id':'0'}) + self.update_commit_cache(cs_cache={"raw_id": "0"}) self.update_commit_cache() def update_commit_cache(self, cs_cache=None, config=None): @@ -2384,6 +2345,7 @@ class Repository(Base, BaseModel): """ from rhodecode.lib.vcs.backends.base import BaseChangeset from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) if cs_cache is None: @@ -2395,8 +2357,7 @@ class Repository(Base, BaseModel): empty = scm_repo is None or scm_repo.is_empty() if not empty: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents", "branch"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents", "branch"]) else: cs_cache = EmptyCommit() @@ -2404,25 +2365,27 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _current_datetime = datetime.datetime.utcnow() - last_change = cs_cache.get('date') or _current_datetime + last_change = cs_cache.get("date") or _current_datetime # we check if last update is newer than the new value # if yes, we use the current timestamp instead. Imagine you get # old commit pushed 1y ago, we'd set last update 1y to ago. last_change_timestamp = datetime_to_time(last_change) current_timestamp = datetime_to_time(last_change) if last_change_timestamp > current_timestamp and not empty: - cs_cache['date'] = _current_datetime + cs_cache["date"] = _current_datetime - _date_latest = parse_datetime(cs_cache.get('date') or empty_date) - cs_cache['updated_on'] = time.time() + _date_latest = parse_datetime(cs_cache.get("date") or empty_date) + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache self.updated_on = last_change Session().add(self) @@ -2434,20 +2397,24 @@ class Repository(Base, BaseModel): else: cs_cache = self.changeset_cache - _date_latest = parse_datetime(cs_cache.get('date') or empty_date) + _date_latest = parse_datetime(cs_cache.get("date") or empty_date) - cs_cache['updated_on'] = time.time() + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache self.updated_on = _date_latest Session().add(self) Session().commit() - log.debug('updated repo `%s` with new commit cache %s, and last update_date: %s', - self.repo_name, cs_cache, _date_latest) + log.debug( + "updated repo `%s` with new commit cache %s, and last update_date: %s", + self.repo_name, + cs_cache, + _date_latest, + ) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2463,8 +2430,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2478,19 +2444,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2510,8 +2471,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2523,18 +2483,18 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - vcs_full_cache = kwargs.pop('vcs_full_cache', None) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + vcs_full_cache = kwargs.pop("vcs_full_cache", None) if vcs_full_cache is not None: # allows override global config full_cache = vcs_full_cache else: - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: - log.debug('Initializing pure cached instance for %s', self.repo_path) + log.debug("Initializing pure cached instance for %s", self.repo_path) return self._get_instance_cached() # cache here is sent to the "vcs server" @@ -2543,10 +2503,9 @@ class Repository(Base, BaseModel): def _get_instance_cached(self): from rhodecode.lib import rc_cache - cache_namespace_uid = f'repo_instance.{self.repo_id}' - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) + cache_namespace_uid = f"repo_instance.{self.repo_id}" + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + region = rc_cache.get_or_create_region("cache_repo_longterm", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) def get_instance_cached(repo_id, context_id, _cache_state_uid): @@ -2556,10 +2515,10 @@ class Repository(Base, BaseModel): # because each thread of gevent needs it's own not shared connection and cache # we also alter `args` so the cache key is individual for every green thread. inv_context_manager = rc_cache.InvalidationContext( - uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, - thread_scoped=True) + uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, thread_scoped=True + ) with inv_context_manager as invalidation_context: - cache_state_uid = invalidation_context.cache_data['cache_state_uid'] + cache_state_uid = invalidation_context.cache_data["cache_state_uid"] args = (self.repo_id, inv_context_manager.cache_key, cache_state_uid) # re-compute and store cache if we get invalidate signal @@ -2568,84 +2527,87 @@ class Repository(Base, BaseModel): else: instance = get_instance_cached(*args) - log.debug('Repo instance fetched in %.4fs', inv_context_manager.compute_time) + log.debug("Repo instance fetched in %.4fs", inv_context_manager.compute_time) return instance def _get_instance(self, cache=True, config=None, repo_state_uid=None): - log.debug('Initializing %s instance `%s` with cache flag set to: %s', - self.repo_type, self.repo_path, cache) + log.debug("Initializing %s instance `%s` with cache flag set to: %s", self.repo_type, self.repo_path, cache) config = config or self._config custom_wire = { - 'cache': cache, # controls the vcs.remote cache - 'repo_state_uid': repo_state_uid + "cache": cache, # controls the vcs.remote cache + "repo_state_uid": repo_state_uid, } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) if repo is not None: repo.count() # cache rebuild return repo def get_shadow_repository_path(self, workspace_id): from rhodecode.lib.vcs.backends.base import BaseRepository - shadow_repo_path = BaseRepository._get_shadow_repository_path( - self.repo_full_path, self.repo_id, workspace_id) + + shadow_repo_path = BaseRepository._get_shadow_repository_path(self.repo_full_path, self.repo_id, workspace_id) return shadow_repo_path def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), + UniqueConstraint("group_name", "group_parent_id"), base_table_args, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) _group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) group_name_hash = Column("repo_group_name_hash", String(1024), nullable=False, unique=False) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', cascade="all, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete-orphan") # no cascade, set NULL - scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_group_id==RepoGroup.group_id') + scope_artifacts = relationship("FileStore", primaryjoin="FileStore.scope_repo_group_id==RepoGroup.group_id") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def group_name(self): @@ -2659,9 +2621,10 @@ class RepoGroup(Base, BaseModel): @classmethod def _load_changeset_cache(cls, repo_id, changeset_cache_raw): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not changeset_cache_raw: - dummy['source_repo_id'] = repo_id + dummy["source_repo_id"] = repo_id return json.loads(json.dumps(dummy)) try: @@ -2674,7 +2637,7 @@ class RepoGroup(Base, BaseModel): @hybrid_property def changeset_cache(self): - return self._load_changeset_cache('', self._changeset_cache) + return self._load_changeset_cache("", self._changeset_cache) @changeset_cache.setter def changeset_cache(self, val): @@ -2683,7 +2646,7 @@ class RepoGroup(Base, BaseModel): except Exception: log.error(traceback.format_exc()) - @validates('group_parent_id') + @validates("group_parent_id") def validate_group_parent_id(self, key, val): """ Check cycle references for a parent group to self @@ -2696,6 +2659,7 @@ class RepoGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod @@ -2708,11 +2672,12 @@ class RepoGroup(Base, BaseModel): c = str(ord(c)) chars.append(c) - return ''.join(chars) + return "".join(chars) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2723,12 +2688,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2738,14 +2702,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2754,15 +2716,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user) \ - .order_by(cls.group_id.asc()) \ - .first() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).order_by(cls.group_id.asc()).first() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2787,14 +2744,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2802,13 +2762,14 @@ class RepoGroup(Base, BaseModel): @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @classmethod def _load_commit_change(cls, last_commit_cache): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = last_commit_cache.get('date', empty_date) + date_latest = last_commit_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2840,9 +2801,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2902,8 +2861,7 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def update_commit_cache(self, config=None): @@ -2922,6 +2880,7 @@ class RepoGroup(Base, BaseModel): """ from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) def repo_groups_and_repos(root_gr): @@ -2933,33 +2892,36 @@ class RepoGroup(Base, BaseModel): latest_repo_cs_cache = {} for obj in repo_groups_and_repos(self): repo_cs_cache = obj.changeset_cache - date_latest = latest_repo_cs_cache.get('date', empty_date) - date_current = repo_cs_cache.get('date', empty_date) + date_latest = latest_repo_cs_cache.get("date", empty_date) + date_current = repo_cs_cache.get("date", empty_date) current_timestamp = datetime_to_time(parse_datetime(date_latest)) if current_timestamp < datetime_to_time(parse_datetime(date_current)): latest_repo_cs_cache = repo_cs_cache - if hasattr(obj, 'repo_id'): - latest_repo_cs_cache['source_repo_id'] = obj.repo_id + if hasattr(obj, "repo_id"): + latest_repo_cs_cache["source_repo_id"] = obj.repo_id else: - latest_repo_cs_cache['source_repo_id'] = repo_cs_cache.get('source_repo_id') + latest_repo_cs_cache["source_repo_id"] = repo_cs_cache.get("source_repo_id") - _date_latest = parse_datetime(latest_repo_cs_cache.get('date') or empty_date) + _date_latest = parse_datetime(latest_repo_cs_cache.get("date") or empty_date) - latest_repo_cs_cache['updated_on'] = time.time() + latest_repo_cs_cache["updated_on"] = time.time() self.changeset_cache = latest_repo_cs_cache self.updated_on = _date_latest Session().add(self) Session().commit() - log.debug('updated repo group `%s` with new commit cache %s, and last update_date: %s', - self.group_name, latest_repo_cs_cache, _date_latest) + log.debug( + "updated repo group `%s` with new commit cache %s, and last update_date: %s", + self.group_name, + latest_repo_cs_cache, + _date_latest, + ) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repository groups """ - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: @@ -2983,9 +2945,11 @@ class RepoGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -3015,19 +2979,19 @@ class RepoGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupRepoGroupToPerm.query()\ - .filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -3040,12 +3004,12 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data @@ -3053,124 +3017,112 @@ class RepoGroup(Base, BaseModel): # Since we transformed `group_name` to a hybrid property, we need to # keep compatibility with the code which uses `group_name` field. result = super(RepoGroup, self).get_dict() - result['group_name'] = result.pop('_group_name', None) + result["group_name"] = result.pop("_group_name", None) return result class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), + Index("p_perm_name_idx", "permission_name"), base_table_args, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch, for backward compat we need same value as before so forced pushed - 'branch.push_force', + "branch.push_force", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -3178,9 +3130,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -3188,24 +3138,26 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms(cls, user_id, repo_id=None): - q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ - .join( - Permission, - UserToRepoBranchPermission.permission_id == Permission.permission_id) \ - .join( - UserRepoToPerm, - UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ + q = ( + Session() + .query(UserToRepoBranchPermission, UserRepoToPerm, Permission) + .join(Permission, UserToRepoBranchPermission.permission_id == Permission.permission_id) + .join(UserRepoToPerm, UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) @@ -3213,46 +3165,33 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ - .join( - Permission, - UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ + q = ( + Session() + .query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) + .join(Permission, UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) .join( UserGroupRepoToPerm, - UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id, + ) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) @@ -3260,102 +3199,81 @@ class Permission(Base, BaseModel): @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserRepoGroupToPerm.permission_id == Permission.permission_id)\ - .join( - RepoGroup, - UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - base_table_args - ) + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id", "permission_id"), base_table_args) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -3367,24 +3285,27 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - base_table_args + __tablename__ = "user_user_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "user_group_id", "permission_id"), base_table_args) + + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -3396,43 +3317,52 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - base_table_args - ) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), base_table_args) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - base_table_args + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), base_table_args) + + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') - user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") + user_group_branch_perms = relationship("UserGroupToRepoBranchPermission", cascade="all") @classmethod def create(cls, users_group, repository, permission): @@ -3444,25 +3374,42 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - base_table_args + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + base_table_args, ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None + ) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3474,39 +3421,54 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - base_table_args + UniqueConstraint( + "users_group_id", + "permission_id", + ), + base_table_args, ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - base_table_args + __tablename__ = "user_repo_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "group_id", "permission_id"), base_table_args) + + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3519,20 +3481,28 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - base_table_args + __tablename__ = "users_group_repo_group_to_perm" + __table_args__ = (UniqueConstraint("users_group_id", "group_id"), base_table_args) + + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3544,43 +3514,51 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - base_table_args - ) + __tablename__ = "statistics" + __table_args__ = base_table_args stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - base_table_args + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + base_table_args, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3588,18 +3566,18 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), base_table_args, ) - CACHE_TYPE_FEED = 'FEED' + CACHE_TYPE_FEED = "FEED" # namespaces used to register process/thread aware caches - REPO_INVALIDATION_NAMESPACE = 'repo_cache:{repo_id}' - SETTINGS_INVALIDATION_NAMESPACE = 'system_settings' + REPO_INVALIDATION_NAMESPACE = "repo_cache:{repo_id}" + SETTINGS_INVALIDATION_NAMESPACE = "system_settings" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) @@ -3607,7 +3585,7 @@ class CacheKey(Base, BaseModel): cache_state_uid = Column("cache_state_uid", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args='', cache_state_uid=None): + def __init__(self, cache_key, cache_args="", cache_state_uid=None): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False @@ -3615,9 +3593,7 @@ class CacheKey(Base, BaseModel): self.cache_state_uid = cache_state_uid or self.generate_new_state_uid() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3667,19 +3643,14 @@ class CacheKey(Base, BaseModel): qry = Session().query(cls).filter(cls.cache_args == cache_uid) if delete: qry.delete() - log.debug('cache objects deleted for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects deleted for cache args %s", safe_str(cache_uid)) else: - qry.update({"cache_active": False, - "cache_state_uid": cls.generate_new_state_uid()}) - log.debug('cache objects marked as invalid for cache args %s', - safe_str(cache_uid)) + qry.update({"cache_active": False, "cache_state_uid": cls.generate_new_state_uid()}) + log.debug("cache objects marked as invalid for cache args %s", safe_str(cache_uid)) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for cache args %s', - safe_str(cache_uid)) + log.exception("Cache key invalidation failed for cache args %s", safe_str(cache_uid)) Session().rollback() @classmethod @@ -3691,49 +3662,51 @@ class CacheKey(Base, BaseModel): @classmethod def get_namespace_map(cls, namespace): - return { - x.cache_key: x - for x in cls.query().filter(cls.cache_args == namespace)} + return {x.cache_key: x for x in cls.query().filter(cls.cache_args == namespace)} class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), + Index("cc_revision_idx", "revision"), base_table_args, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') - resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, back_populates="resolved_by") + resolved_by = relationship("ChangesetComment", back_populates="resolved_comment") - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3744,8 +3717,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3756,7 +3728,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3792,27 +3764,26 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on, - 'comment_resolved_by': self.resolved + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, + "comment_resolved_by": self.resolved, } return data @@ -3823,18 +3794,18 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - base_table_args + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + base_table_args, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3843,26 +3814,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3875,8 +3843,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3899,8 +3867,7 @@ class _SetState(object): self._current_state = None def __enter__(self): - log.debug('StateLock: entering set state context of pr %s, setting state to: `%s`', - self._pr, self._pr_state) + log.debug("StateLock: entering set state context of pr %s, setting state to: `%s`", self._pr, self._pr_state) self.set_pr_state(self._pr_state) return self @@ -3910,8 +3877,7 @@ class _SetState(object): return None self.set_pr_state(self._org_state) - log.debug('StateLock: exiting set state context of pr %s, setting state to: `%s`', - self._pr, self._org_state) + log.debug("StateLock: exiting set state context of pr %s, setting state to: `%s`", self._pr, self._org_state) @property def state(self): @@ -3924,7 +3890,7 @@ class _SetState(object): Session().commit() self._current_state = pr_state except Exception: - log.exception('Failed to set PullRequest %s state to %s', self._pr, pr_state) + log.exception("Failed to set PullRequest %s state to %s", self._pr, pr_state) raise @@ -3934,51 +3900,40 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" # available states - STATE_CREATING = u'creating' - STATE_UPDATING = u'updating' - STATE_MERGING = u'merging' - STATE_CREATED = u'created' + STATE_CREATING = "creating" + STATE_UPDATING = "updating" + STATE_MERGING = "merging" + STATE_CREATED = "created" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) - description_renderer = Column('description_renderer', Unicode(64), nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + description_renderer = Column("description_renderer", Unicode(64), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) pull_request_state = Column("pull_request_state", String(255), nullable=True) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _source_ref = Column('org_ref', Unicode(255), nullable=False) + _source_ref = Column("org_ref", Unicode(255), nullable=False) @hybrid_property def source_ref(self): @@ -3986,13 +3941,12 @@ class _PullRequestBase(BaseModel): @source_ref.setter def source_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._source_ref = safe_str(val) - _target_ref = Column('other_ref', Unicode(255), nullable=False) + _target_ref = Column("other_ref", Unicode(255), nullable=False) @hybrid_property def target_ref(self): @@ -4000,37 +3954,32 @@ class _PullRequestBase(BaseModel): @target_ref.setter def target_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._target_ref = safe_str(val) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) last_merge_metadata = Column( - 'last_merge_metadata', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "last_merge_metadata", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) - merge_rev = Column('merge_rev', String(40), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -4040,22 +3989,23 @@ class _PullRequestBase(BaseModel): def work_in_progress(self): """checks if pull request is work in progress by checking the title""" title = self.title.upper() - if re.match(r'^(\[WIP\]\s*|WIP:\s*|WIP\s+)', title): + if re.match(r"^(\[WIP\]\s*|WIP:\s*|WIP\s+)", title): return True return False @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = u':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -4067,13 +4017,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -4081,9 +4029,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -4104,7 +4050,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -4116,7 +4062,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -4125,66 +4071,59 @@ class _PullRequestBase(BaseModel): pull_request = self if with_merge_state: - merge_response, merge_status, msg = \ - PullRequestModel().merge_status(pull_request) + merge_response, merge_status, msg = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status, - 'message': safe_str(msg), + "status": merge_status, + "message": safe_str(msg), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'state': pull_request.pull_request_state, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "state": pull_request.pull_request_state, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data @@ -4205,30 +4144,24 @@ class _PullRequestBase(BaseModel): class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_requests" + __table_args__ = (base_table_args,) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', cascade="all, delete-orphan") - statuses = relationship('ChangesetStatus', cascade="all, delete-orphan") - comments = relationship('ChangesetComment', cascade="all, delete-orphan") - versions = relationship('PullRequestVersion', cascade="all, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -4239,7 +4172,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -4247,15 +4180,13 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @@ -4265,20 +4196,17 @@ class PullRequest(Base, _PullRequestBase): @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data(with_merge_state=False)) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -4298,22 +4226,22 @@ class PullRequest(Base, _PullRequestBase): return self.pull_request_state != PullRequest.STATE_CREATED def __json__(self): - return { - 'revisions': self.revisions, - 'versions': self.versions_count - } + return {"revisions": self.revisions, "versions": self.versions_count} def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): @@ -4333,23 +4261,18 @@ class PullRequest(Base, _PullRequestBase): class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_versions" + __table_args__ = (base_table_args,) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -4374,10 +4297,8 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = (base_table_args,) @hybrid_property def reasons(self): @@ -4389,80 +4310,73 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), + Index("notification_type_idx", "type"), base_table_args, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' - TYPE_PULL_REQUEST_UPDATE = u'pull_request_update' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" + TYPE_PULL_REQUEST_UPDATE = "pull_request_update" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -4494,20 +4408,22 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' - __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - base_table_args + __tablename__ = "user_to_notification" + __table_args__ = (UniqueConstraint("user_id", "notification_id"), base_table_args) + + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) - - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -4515,68 +4431,69 @@ class UserNotification(Base, BaseModel): class UserNotice(Base, BaseModel): - __tablename__ = 'user_notices' - __table_args__ = ( - base_table_args + __tablename__ = "user_notices" + __table_args__ = base_table_args + + NOTIFICATION_TYPE_MESSAGE = "message" + NOTIFICATION_TYPE_NOTICE = "notice" + + NOTIFICATION_LEVEL_INFO = "info" + NOTIFICATION_LEVEL_WARNING = "warning" + NOTIFICATION_LEVEL_ERROR = "error" + + user_notice_id = Column("gist_id", Integer(), primary_key=True) + + notice_subject = Column("notice_subject", Unicode(512), nullable=True) + notice_body = Column("notice_body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + + notice_read = Column("notice_read", Boolean, default=False) + + notification_level = Column("notification_level", String(1024), default=NOTIFICATION_LEVEL_INFO) + notification_type = Column("notification_type", String(1024), default=NOTIFICATION_TYPE_NOTICE) + + notice_created_by = Column("notice_created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + notice_created_on = Column( + "notice_created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now ) - NOTIFICATION_TYPE_MESSAGE = 'message' - NOTIFICATION_TYPE_NOTICE = 'notice' - - NOTIFICATION_LEVEL_INFO = 'info' - NOTIFICATION_LEVEL_WARNING = 'warning' - NOTIFICATION_LEVEL_ERROR = 'error' - - user_notice_id = Column('gist_id', Integer(), primary_key=True) - - notice_subject = Column('notice_subject', Unicode(512), nullable=True) - notice_body = Column('notice_body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - - notice_read = Column('notice_read', Boolean, default=False) - - notification_level = Column('notification_level', String(1024), default=NOTIFICATION_LEVEL_INFO) - notification_type = Column('notification_type', String(1024), default=NOTIFICATION_TYPE_NOTICE) - - notice_created_by = Column('notice_created_by', Integer(), ForeignKey('users.user_id'), nullable=True) - notice_created_on = Column('notice_created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - - user_id = Column('user_id', Integer(), ForeignKey('users.user_id')) - user = relationship('User', lazy="joined", primaryjoin='User.user_id==UserNotice.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id")) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==UserNotice.user_id") class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - base_table_args + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + base_table_args, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -4594,6 +4511,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -4604,8 +4522,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4615,24 +4533,24 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): @@ -4642,27 +4560,26 @@ class Gist(Base, BaseModel): :param kwargs: """ from rhodecode.model.gist import GistModel + full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False, - _vcs_alias=GistModel.vcs_backend) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False, _vcs_alias=GistModel.vcs_backend) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - base_table_args + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + base_table_args, ) - external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): @@ -4710,36 +4627,30 @@ class ExternalIdentity(Base, BaseModel): @classmethod def load_provider_plugin(cls, plugin_id): from rhodecode.authentication.base import loadplugin - _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) + + _plugin_id = "egg:rhodecode-enterprise-ee#{}".format(plugin_id) auth_plugin = loadplugin(_plugin_id) return auth_plugin class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - base_table_args - ) + __tablename__ = "integrations" + __table_args__ = base_table_args - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4747,118 +4658,109 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = base_table_args - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = base_table_args VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules" + __table_args__ = base_table_args - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_pattern(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_pattern(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_pattern(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -4869,37 +4771,37 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - if self.source_branch_pattern.startswith('re:'): + if self.source_branch_pattern.startswith("re:"): source_pattern = self.source_branch_pattern[3:] else: - source_pattern = '^' + glob2re(self.source_branch_pattern) + '$' + source_pattern = "^" + glob2re(self.source_branch_pattern) + "$" source_branch_regex = re.compile(source_pattern) source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - if self.target_branch_pattern.startswith('re:'): + if self.target_branch_pattern.startswith("re:"): target_pattern = self.target_branch_pattern[3:] else: - target_pattern = '^' + glob2re(self.target_branch_pattern) + '$' + target_pattern = "^" + glob2re(self.target_branch_pattern) + "$" target_branch_regex = re.compile(target_pattern) target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False - if self.file_pattern.startswith('re:'): + if self.file_pattern.startswith("re:"): file_pattern = self.file_pattern[3:] else: file_pattern = glob2re(self.file_pattern) @@ -4913,7 +4815,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4921,17 +4823,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -4943,16 +4845,15 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def user_group_vote_rule(self, user_id): - rules = [] if not self.rule_user_groups: return rules @@ -4964,39 +4865,45 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), base_table_args, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -5005,8 +4912,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -5027,8 +4933,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -5046,6 +4951,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -5064,7 +4970,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -5084,16 +4990,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -5105,19 +5010,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -5128,86 +5033,112 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class UserBookmark(Base, BaseModel): - __tablename__ = 'user_bookmarks' + __tablename__ = "user_bookmarks" __table_args__ = ( - UniqueConstraint('user_id', 'bookmark_repo_id'), - UniqueConstraint('user_id', 'bookmark_repo_group_id'), - UniqueConstraint('user_id', 'bookmark_position'), - base_table_args + UniqueConstraint("user_id", "bookmark_repo_id"), + UniqueConstraint("user_id", "bookmark_repo_group_id"), + UniqueConstraint("user_id", "bookmark_position"), + base_table_args, ) - user_bookmark_id = Column("user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user_bookmark_id = Column( + "user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) position = Column("bookmark_position", Integer(), nullable=False) title = Column("bookmark_title", String(255), nullable=True, unique=None, default=None) redirect_url = Column("bookmark_redirect_url", String(10240), nullable=True, unique=None, default=None) created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - bookmark_repo_id = Column("bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) - bookmark_repo_group_id = Column("bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None) + bookmark_repo_id = Column( + "bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + bookmark_repo_group_id = Column( + "bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) user = relationship("User") @@ -5216,95 +5147,112 @@ class UserBookmark(Base, BaseModel): @classmethod def get_by_position_for_user(cls, position, user_id): - return cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .filter(UserBookmark.position == position).scalar() + return cls.query().filter(UserBookmark.user_id == user_id).filter(UserBookmark.position == position).scalar() @classmethod def get_bookmarks_for_user(cls, user_id, cache=True): - bookmarks = cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .options(joinedload(UserBookmark.repository)) \ - .options(joinedload(UserBookmark.repository_group)) \ + bookmarks = ( + cls.query() + .filter(UserBookmark.user_id == user_id) + .options(joinedload(UserBookmark.repository)) + .options(joinedload(UserBookmark.repository_group)) .order_by(UserBookmark.position.asc()) + ) if cache: - bookmarks = bookmarks.options( - FromCache("sql_cache_short", "get_user_{}_bookmarks".format(user_id)) - ) + bookmarks = bookmarks.options(FromCache("sql_cache_short", "get_user_{}_bookmarks".format(user_id))) return bookmarks.all() def __unicode__(self): - return u'' % (self.position, self.redirect_url) + return "" % (self.position, self.redirect_url) class FileStore(Base, BaseModel): - __tablename__ = 'file_store' - __table_args__ = ( - base_table_args - ) + __tablename__ = "file_store" + __table_args__ = base_table_args - file_store_id = Column('file_store_id', Integer(), primary_key=True) - file_uid = Column('file_uid', String(1024), nullable=False) - file_display_name = Column('file_display_name', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), nullable=True) - file_description = Column('file_description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - file_org_name = Column('file_org_name', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=False) + file_store_id = Column("file_store_id", Integer(), primary_key=True) + file_uid = Column("file_uid", String(1024), nullable=False) + file_display_name = Column( + "file_display_name", UnicodeText().with_variant(UnicodeText(2048), "mysql"), nullable=True + ) + file_description = Column( + "file_description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True + ) + file_org_name = Column("file_org_name", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=False) # sha256 hash - file_hash = Column('file_hash', String(512), nullable=False) - file_size = Column('file_size', BigInteger(), nullable=False) + file_hash = Column("file_hash", String(512), nullable=False) + file_size = Column("file_size", BigInteger(), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True) - accessed_count = Column('accessed_count', Integer(), default=0) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True) + accessed_count = Column("accessed_count", Integer(), default=0) - enabled = Column('enabled', Boolean(), nullable=False, default=True) + enabled = Column("enabled", Boolean(), nullable=False, default=True) # if repo/repo_group reference is set, check for permissions - check_acl = Column('check_acl', Boolean(), nullable=False, default=True) + check_acl = Column("check_acl", Boolean(), nullable=False, default=True) # hidden defines an attachment that should be hidden from showing in artifact listing - hidden = Column('hidden', Boolean(), nullable=False, default=False) + hidden = Column("hidden", Boolean(), nullable=False, default=False) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - upload_user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + upload_user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.user_id") - file_metadata = relationship('FileStoreMetadata', lazy='joined') + file_metadata = relationship("FileStoreMetadata", lazy="joined") # scope limited to user, which requester have access to scope_user_id = Column( - 'scope_user_id', Integer(), ForeignKey('users.user_id'), - nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.scope_user_id') + "scope_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.scope_user_id") # scope limited to user group, which requester have access to scope_user_group_id = Column( - 'scope_user_group_id', Integer(), ForeignKey('users_groups.users_group_id'), - nullable=True, unique=None, default=None) - user_group = relationship('UserGroup', lazy='joined') + "scope_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=True, + unique=None, + default=None, + ) + user_group = relationship("UserGroup", lazy="joined") # scope limited to repo, which requester have access to scope_repo_id = Column( - 'scope_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + "scope_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + repo = relationship("Repository", lazy="joined") # scope limited to repo group, which requester have access to scope_repo_group_id = Column( - 'scope_repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "scope_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @classmethod def get_by_store_uid(cls, file_store_uid): return FileStore.query().filter(FileStore.file_uid == file_store_uid).scalar() @classmethod - def create(cls, file_uid, filename, file_hash, file_size, file_display_name='', - file_description='', enabled=True, hidden=False, check_acl=True, - user_id=None, scope_user_id=None, scope_repo_id=None, scope_repo_group_id=None): - + def create( + cls, + file_uid, + filename, + file_hash, + file_size, + file_display_name="", + file_description="", + enabled=True, + hidden=False, + check_acl=True, + user_id=None, + scope_user_id=None, + scope_repo_id=None, + scope_repo_group_id=None, + ): store_entry = FileStore() store_entry.file_uid = file_uid store_entry.file_display_name = file_display_name @@ -5331,14 +5279,16 @@ class FileStore(Base, BaseModel): return for section, key, value, value_type in args: - has_key = FileStoreMetadata().query() \ - .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) \ - .filter(FileStoreMetadata.file_store_meta_section == section) \ - .filter(FileStoreMetadata.file_store_meta_key == key) \ + has_key = ( + FileStoreMetadata() + .query() + .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) + .filter(FileStoreMetadata.file_store_meta_section == section) + .filter(FileStoreMetadata.file_store_meta_key == key) .scalar() + ) if has_key: - msg = 'key `{}` already defined under section `{}` for this file.'\ - .format(key, section) + msg = "key `{}` already defined under section `{}` for this file.".format(key, section) raise ArtifactMetadataDuplicate(msg, err_section=section, err_key=key) # NOTE(marcink): raises ArtifactMetadataBadValueType @@ -5358,86 +5308,99 @@ class FileStore(Base, BaseModel): Session().commit() except IntegrityError: Session().rollback() - raise ArtifactMetadataDuplicate('Duplicate section/key found for this file.') + raise ArtifactMetadataDuplicate("Duplicate section/key found for this file.") @classmethod def bump_access_counter(cls, file_uid, commit=True): - FileStore().query()\ - .filter(FileStore.file_uid == file_uid)\ - .update({FileStore.accessed_count: (FileStore.accessed_count + 1), - FileStore.accessed_on: datetime.datetime.now()}) + FileStore().query().filter(FileStore.file_uid == file_uid).update( + {FileStore.accessed_count: (FileStore.accessed_count + 1), FileStore.accessed_on: datetime.datetime.now()} + ) if commit: Session().commit() def __json__(self): data = { - 'filename': self.file_display_name, - 'filename_org': self.file_org_name, - 'file_uid': self.file_uid, - 'description': self.file_description, - 'hidden': self.hidden, - 'size': self.file_size, - 'created_on': self.created_on, - 'uploaded_by': self.upload_user.get_api_data(details='basic'), - 'downloaded_times': self.accessed_count, - 'sha256': self.file_hash, - 'metadata': self.file_metadata, + "filename": self.file_display_name, + "filename_org": self.file_org_name, + "file_uid": self.file_uid, + "description": self.file_description, + "hidden": self.hidden, + "size": self.file_size, + "created_on": self.created_on, + "uploaded_by": self.upload_user.get_api_data(details="basic"), + "downloaded_times": self.accessed_count, + "sha256": self.file_hash, + "metadata": self.file_metadata, } return data def __repr__(self): - return ''.format(self.file_store_id) + return "".format(self.file_store_id) class FileStoreMetadata(Base, BaseModel): - __tablename__ = 'file_store_metadata' + __tablename__ = "file_store_metadata" __table_args__ = ( - UniqueConstraint('file_store_id', 'file_store_meta_section_hash', 'file_store_meta_key_hash'), - Index('file_store_meta_section_idx', 'file_store_meta_section', mysql_length=255), - Index('file_store_meta_key_idx', 'file_store_meta_key', mysql_length=255), - base_table_args + UniqueConstraint("file_store_id", "file_store_meta_section_hash", "file_store_meta_key_hash"), + Index("file_store_meta_section_idx", "file_store_meta_section", mysql_length=255), + Index("file_store_meta_key_idx", "file_store_meta_key", mysql_length=255), + base_table_args, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } file_store_meta_id = Column( - "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) + "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) _file_store_meta_section = Column( - "file_store_meta_section", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_section", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_section_hash = Column( - "file_store_meta_section_hash", String(255), - nullable=True, unique=None, default=None) + "file_store_meta_section_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_key = Column( - "file_store_meta_key", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_key", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_key_hash = Column( - "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None) + "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_value = Column( - "file_store_meta_value", UnicodeText().with_variant(UnicodeText(20480), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_value", + UnicodeText().with_variant(UnicodeText(20480), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_value_type = Column( - "file_store_meta_value_type", String(255), nullable=True, unique=None, - default='unicode') + "file_store_meta_value_type", String(255), nullable=True, unique=None, default="unicode" + ) file_store_id = Column( - 'file_store_id', Integer(), ForeignKey('file_store.file_store_id'), - nullable=True, unique=None, default=None) + "file_store_id", Integer(), ForeignKey("file_store.file_store_id"), nullable=True, unique=None, default=None + ) - file_store = relationship('FileStore', lazy='joined') + file_store = relationship("FileStore", lazy="joined") @classmethod def valid_value_type(cls, value): - if value.split('.')[0] not in cls.SETTINGS_TYPES: + if value.split(".")[0] not in cls.SETTINGS_TYPES: raise ArtifactMetadataBadValueType( - 'value_type must be one of %s got %s' % (cls.SETTINGS_TYPES.keys(), value)) + "value_type must be one of %s got %s" % (cls.SETTINGS_TYPES.keys(), value) + ) @hybrid_property def file_store_meta_section(self): @@ -5463,13 +5426,13 @@ class FileStoreMetadata(Base, BaseModel): if self._file_store_meta_value_type: # e.g unicode.encrypted == unicode - _type = self._file_store_meta_value_type.split('.')[0] + _type = self._file_store_meta_value_type.split(".")[0] # decode the encrypted value if it's encrypted field type - if '.encrypted' in self._file_store_meta_value_type: + if ".encrypted" in self._file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_result_value(val, None)) # do final type conversion - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] val = converter(val) return val @@ -5478,7 +5441,7 @@ class FileStoreMetadata(Base, BaseModel): def file_store_meta_value(self, val): val = safe_str(val) # encode the encrypted value - if '.encrypted' in self.file_store_meta_value_type: + if ".encrypted" in self.file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._file_store_meta_value = val @@ -5495,28 +5458,30 @@ class FileStoreMetadata(Base, BaseModel): def __json__(self): data = { - 'artifact': self.file_store.file_uid, - 'section': self.file_store_meta_section, - 'key': self.file_store_meta_key, - 'value': self.file_store_meta_value, + "artifact": self.file_store.file_uid, + "section": self.file_store_meta_section, + "key": self.file_store_meta_key, + "value": self.file_store_meta_value, } return data def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.file_store_meta_section, - self.file_store_meta_key, self.file_store_meta_value) + return "<%s[%s]%s=>%s]>" % ( + self.__class__.__name__, + self.file_store_meta_section, + self.file_store_meta_key, + self.file_store_meta_value, + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_migrate_version" + __table_args__ = (base_table_args,) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) @classmethod def set_version(cls, version): @@ -5529,16 +5494,14 @@ class DbMigrateVersion(Base, BaseModel): class DbSession(Base, BaseModel): - __tablename__ = 'db_session' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_session" + __table_args__ = (base_table_args,) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_19_0_2.py b/rhodecode/lib/dbmigrate/schema/db_4_19_0_2.py index 5e347541..cd4c8759 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_19_0_2.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_19_0_2.py @@ -35,14 +35,34 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, cast, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType, BigInteger) + or_, + and_, + not_, + func, + cast, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, + BigInteger, +) from sqlalchemy.sql.expression import true, false, case from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -55,20 +75,30 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance, VCSError from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, sha1_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + sha1_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, + datetime_to_time, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher, validate_and_decrypt_data from rhodecode.lib.encrypt2 import Encryptor -from rhodecode.lib.exceptions import ( - ArtifactMetadataDuplicate, ArtifactMetadataBadValueType) +from rhodecode.lib.exceptions import ArtifactMetadataDuplicate, ArtifactMetadataBadValueType from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -83,10 +113,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -98,8 +128,8 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -110,7 +140,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -134,18 +164,16 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts base_table_args = { - 'extend_existing': True, - 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', - 'sqlite_autoincrement': True + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, } @@ -158,6 +186,7 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): @@ -165,23 +194,21 @@ class EncryptedTextValue(TypeDecorator): Setter for storing value """ import rhodecode + if not value: return value # protect against double encrypting if values is already encrypted - if value.startswith('enc$aes$') \ - or value.startswith('enc$aes_hmac$') \ - or value.startswith('enc2$'): - raise ValueError('value needs to be in unencrypted format, ' - 'ie. not starting with enc$ or enc2$') + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$") or value.startswith("enc2$"): + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$ or enc2$") - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - if algo == 'aes': - return 'enc$aes_hmac$%s' % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) - elif algo == 'fernet': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + if algo == "aes": + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).encrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) def process_result_value(self, value, dialect): """ @@ -189,17 +216,18 @@ class EncryptedTextValue(TypeDecorator): """ import rhodecode + if not value: return value - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - enc_strict_mode = str2bool(rhodecode.CONFIG.get('rhodecode.encrypted_values.strict') or True) - if algo == 'aes': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) + if algo == "aes": decrypted_data = validate_and_decrypt_data(value, ENCRYPTION_KEY, enc_strict_mode) - elif algo == 'fernet': + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).decrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) return decrypted_data @@ -210,20 +238,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -234,11 +262,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -295,48 +328,47 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = ( - UniqueConstraint('app_settings_name'), - base_table_args - ) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), base_table_args) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -346,14 +378,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -365,7 +396,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -376,40 +407,35 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val @classmethod def get_by_prefix(cls, prefix): - return RhodeCodeSetting.query()\ - .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ - .all() + return RhodeCodeSetting.query().filter(RhodeCodeSetting.app_settings_name.startswith(prefix)).all() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = ( - UniqueConstraint('ui_key'), - base_table_args - ) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), base_table_args) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" HOOKS_BUILTIN = [ HOOK_PRE_PULL, @@ -424,60 +450,41 @@ class RhodeCodeUi(Base, BaseModel): # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - base_table_args + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -487,7 +494,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -507,62 +514,60 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - base_table_args + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - base_table_args + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + base_table_args, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -573,65 +578,75 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all, delete-orphan') + user_log = relationship("UserLog") + user_perms = relationship( + "UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all, delete-orphan" + ) - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all, delete-orphan') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') + repo_to_perm = relationship( + "UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities external_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") # artifacts owned - artifacts = relationship('FileStore', primaryjoin='FileStore.user_id==User.user_id') + artifacts = relationship("FileStore", primaryjoin="FileStore.user_id==User.user_id") # no cascade, set NULL - scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_user_id==User.user_id') + scope_artifacts = relationship("FileStore", primaryjoin="FileStore.scope_user_id==User.user_id") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -644,6 +659,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -651,6 +667,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -660,11 +677,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -677,10 +696,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -689,20 +710,13 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] def emails_cached(self): - emails = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) + emails = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()) - emails = emails.options( - FromCache("sql_cache_short", "get_user_{}_emails".format(self.user_id)) - ) + emails = emails.options(FromCache("sql_cache_short", "get_user_{}_emails".format(self.user_id))) return [self.email] + [x.email for x in emails] @@ -712,44 +726,43 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @LazyProperty def artifact_token(self): return self.get_artifact_token() def get_artifact_token(self, cache=True): - artifacts_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ + artifacts_tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == self) .filter(UserApiKeys.role == UserApiKeys.ROLE_ARTIFACT_DOWNLOAD) + ) if cache: artifacts_tokens = artifacts_tokens.options( - FromCache("sql_cache_short", "get_user_artifact_token_%s" % self.user_id)) + FromCache("sql_cache_short", "get_user_artifact_token_%s" % self.user_id) + ) artifacts_tokens = artifacts_tokens.all() if artifacts_tokens: return artifacts_tokens[0].api_key - return 'NO_ARTIFACT_TOKEN_AVAILABLE' + return "NO_ARTIFACT_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -758,34 +771,34 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -798,8 +811,10 @@ class User(Base, BaseModel): else: plain_token_map[token.api_key] = token log.debug( - 'Found %s plain and %s encrypted tokens to check for authentication for this user', - len(plain_token_map), len(enc_token_map)) + "Found %s plain and %s encrypted tokens to check for authentication for this user", + len(plain_token_map), + len(enc_token_map), + ) # plain token match comes first match = plain_token_map.get(auth_token) @@ -813,16 +828,18 @@ class User(Base, BaseModel): break if match: - log.debug('Found matching token %s', match) + log.debug("Found matching token %s", match) if match.repo_id: - log.debug('Found scope, checking for scope match of token %s', match) + log.debug("Found scope, checking for scope match of token %s", match) if match.repo_id == scope_repo_id: return True else: log.debug( - 'AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - match.repo, scope_repo_id) + "AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + match.repo, + scope_repo_id, + ) return False else: return True @@ -836,29 +853,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -866,13 +882,14 @@ class User(Base, BaseModel): @property def language(self): - return self.user_data.get('language') + return self.user_data.get("language") def AuthUser(self, **kwargs): """ Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -888,44 +905,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -933,7 +947,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -942,8 +955,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -955,9 +967,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -969,6 +980,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -987,13 +999,13 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with %s', kwargs) + log.debug("updated userdata with %s", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -1003,13 +1015,10 @@ class User(Base, BaseModel): @classmethod def get_first_super_admin(cls): - user = User.query()\ - .filter(User.admin == true()) \ - .order_by(User.user_id.asc()) \ - .first() + user = User.query().filter(User.admin == true()).order_by(User.user_id.asc()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -1037,7 +1046,7 @@ class User(Base, BaseModel): def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -1049,16 +1058,18 @@ class User(Base, BaseModel): @classmethod def get_default_user_id(cls): import rhodecode - return rhodecode.CONFIG['default_user_id'] - def _get_default_perms(self, user, suffix=''): + return rhodecode.CONFIG["default_user_id"] + + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -1072,99 +1083,91 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'description': user.description, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "description": user.description, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - base_table_args + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + base_table_args, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_ARTIFACT_DOWNLOAD = 'role_artifact_download' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_ARTIFACT_DOWNLOAD = "role_artifact_download" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED, ROLE_ARTIFACT_DOWNLOAD] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1172,12 +1175,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1189,12 +1193,12 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), - cls.ROLE_ARTIFACT_DOWNLOAD: _('artifacts downloads'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), + cls.ROLE_ARTIFACT_DOWNLOAD: _("artifacts downloads"), }.get(role, role) @property @@ -1203,10 +1207,10 @@ class UserApiKeys(Base, BaseModel): def _get_scope(self): if self.repo: - return 'Repository: {}'.format(self.repo.repo_name) + return "Repository: {}".format(self.repo.repo_name) if self.repo_group: - return 'RepositoryGroup: {} (recursive)'.format(self.repo_group.group_name) - return 'Global' + return "RepositoryGroup: {} (recursive)".format(self.repo_group.group_name) + return "Global" @property def scope_humanized(self): @@ -1219,25 +1223,20 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' - __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - base_table_args - ) - + __tablename__ = "user_email_map" + __table_args__ = (Index("uem_email_idx", "email"), UniqueConstraint("email"), base_table_args) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1250,23 +1249,20 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' - __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - base_table_args - ) - + __tablename__ = "user_ip_map" + __table_args__ = (UniqueConstraint("user_id", "ip_addr"), base_table_args) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1276,43 +1272,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - base_table_args + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + base_table_args, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1322,41 +1314,47 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "user_logs" + __table_args__ = (base_table_args,) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1367,34 +1365,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "users_groups" + __table_args__ = (base_table_args,) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1409,6 +1411,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1429,29 +1432,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1461,16 +1459,14 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for user groups """ - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: @@ -1494,9 +1490,11 @@ class UserGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1526,29 +1524,30 @@ class UserGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupUserGroupToPerm.query()\ - .filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.user_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.user_group.members] + entry.members = [x.user.get_dict() for x in _user_group.user_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1559,13 +1558,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1573,207 +1572,182 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - base_table_args, + __tablename__ = "users_groups_members" + __table_args__ = (base_table_args,) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field + UniqueConstraint("repository_id", "field_key"), # no-multi field base_table_args, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), + Index("r_repo_name_idx", "repo_name", mysql_length=255), base_table_args, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - archived = Column( - "archived", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + archived = Column("archived", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.source_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.target_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") # no cascade, set NULL - artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_id==Repository.repo_id') + artifacts = relationship("FileStore", primaryjoin="FileStore.scope_repo_id==Repository.repo_id") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1782,16 +1756,17 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @classmethod def _load_changeset_cache(cls, repo_id, changeset_cache_raw): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not changeset_cache_raw: - dummy['source_repo_id'] = repo_id + dummy["source_repo_id"] = repo_id return json.loads(json.dumps(dummy)) try: @@ -1840,13 +1815,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1878,14 +1852,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True, archived=False): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True, archived=False): q = Repository.query() if not archived: @@ -1906,7 +1878,7 @@ class Repository(Base, BaseModel): @property def repo_uid(self): - return '_{}'.format(self.repo_id) + return "_{}".format(self.repo_id) @property def forks(self): @@ -1935,7 +1907,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1953,8 +1925,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1972,12 +1943,8 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - return CacheKey.query()\ - .filter(CacheKey.cache_args == invalidation_namespace)\ - .order_by(CacheKey.cache_key)\ - .all() + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + return CacheKey.query().filter(CacheKey.cache_args == invalidation_namespace).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -1986,16 +1953,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -2004,10 +1967,8 @@ class Repository(Base, BaseModel): return [] def shadow_repos(self): - shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id) - return [ - x for x in os.listdir(os.path.dirname(self.repo_full_path)) - if x.startswith(shadow_repos_pattern)] + shadow_repos_pattern = ".__shadow_repo_{}".format(self.repo_id) + return [x for x in os.listdir(os.path.dirname(self.repo_full_path)) if x.startswith(shadow_repos_pattern)] def get_new_name(self, repo_name): """ @@ -2024,14 +1985,14 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repositories """ - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: @@ -2057,9 +2018,11 @@ class Repository(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2094,19 +2057,19 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=True): - q = UserGroupRepoToPerm.query()\ - .filter(UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2128,33 +2091,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2202,7 +2163,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2215,53 +2176,52 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @classmethod def _load_commit_change(cls, last_commit_cache): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = last_commit_cache.get('date', empty_date) + date_latest = last_commit_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2280,9 +2240,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2290,62 +2251,64 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides request = get_current_request() if not uri_tmpl: - if hasattr(request, 'call_context') and hasattr(request.call_context, 'rc_config'): + if hasattr(request, "call_context") and hasattr(request.call_context, "rc_config"): rc_config = request.call_context.rc_config else: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, - repo_type=self.repo_type, - **override) + return get_clone_url( + request=request, + uri_tmpl=uri_tmpl, + repo_name=self.repo_name, + repo_id=self.repo_id, + repo_type=self.repo_type, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, maybe_unreachable=False): return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load, - maybe_unreachable=maybe_unreachable) + self.scm_instance(), commit_id, commit_idx, pre_load=pre_load, maybe_unreachable=maybe_unreachable + ) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2355,8 +2318,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2369,7 +2331,7 @@ class Repository(Base, BaseModel): return commit def flush_commit_cache(self): - self.update_commit_cache(cs_cache={'raw_id':'0'}) + self.update_commit_cache(cs_cache={"raw_id": "0"}) self.update_commit_cache() def update_commit_cache(self, cs_cache=None, config=None): @@ -2390,6 +2352,7 @@ class Repository(Base, BaseModel): """ from rhodecode.lib.vcs.backends.base import BaseChangeset from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) if cs_cache is None: @@ -2401,8 +2364,7 @@ class Repository(Base, BaseModel): empty = scm_repo is None or scm_repo.is_empty() if not empty: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents", "branch"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents", "branch"]) else: cs_cache = EmptyCommit() @@ -2410,25 +2372,27 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _current_datetime = datetime.datetime.utcnow() - last_change = cs_cache.get('date') or _current_datetime + last_change = cs_cache.get("date") or _current_datetime # we check if last update is newer than the new value # if yes, we use the current timestamp instead. Imagine you get # old commit pushed 1y ago, we'd set last update 1y to ago. last_change_timestamp = datetime_to_time(last_change) current_timestamp = datetime_to_time(last_change) if last_change_timestamp > current_timestamp and not empty: - cs_cache['date'] = _current_datetime + cs_cache["date"] = _current_datetime - _date_latest = parse_datetime(cs_cache.get('date') or empty_date) - cs_cache['updated_on'] = time.time() + _date_latest = parse_datetime(cs_cache.get("date") or empty_date) + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache self.updated_on = last_change Session().add(self) @@ -2440,20 +2404,24 @@ class Repository(Base, BaseModel): else: cs_cache = self.changeset_cache - _date_latest = parse_datetime(cs_cache.get('date') or empty_date) + _date_latest = parse_datetime(cs_cache.get("date") or empty_date) - cs_cache['updated_on'] = time.time() + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache self.updated_on = _date_latest Session().add(self) Session().commit() - log.debug('updated repo `%s` with new commit cache %s, and last update_date: %s', - self.repo_name, cs_cache, _date_latest) + log.debug( + "updated repo `%s` with new commit cache %s, and last update_date: %s", + self.repo_name, + cs_cache, + _date_latest, + ) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2469,8 +2437,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2484,19 +2451,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2516,8 +2478,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2529,18 +2490,18 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - vcs_full_cache = kwargs.pop('vcs_full_cache', None) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + vcs_full_cache = kwargs.pop("vcs_full_cache", None) if vcs_full_cache is not None: # allows override global config full_cache = vcs_full_cache else: - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: - log.debug('Initializing pure cached instance for %s', self.repo_path) + log.debug("Initializing pure cached instance for %s", self.repo_path) return self._get_instance_cached() # cache here is sent to the "vcs server" @@ -2549,10 +2510,9 @@ class Repository(Base, BaseModel): def _get_instance_cached(self): from rhodecode.lib import rc_cache - cache_namespace_uid = f'repo_instance.{self.repo_id}' - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) + cache_namespace_uid = f"repo_instance.{self.repo_id}" + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + region = rc_cache.get_or_create_region("cache_repo_longterm", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) def get_instance_cached(repo_id, context_id, _cache_state_uid): @@ -2562,10 +2522,10 @@ class Repository(Base, BaseModel): # because each thread of gevent needs it's own not shared connection and cache # we also alter `args` so the cache key is individual for every green thread. inv_context_manager = rc_cache.InvalidationContext( - uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, - thread_scoped=True) + uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, thread_scoped=True + ) with inv_context_manager as invalidation_context: - cache_state_uid = invalidation_context.cache_data['cache_state_uid'] + cache_state_uid = invalidation_context.cache_data["cache_state_uid"] args = (self.repo_id, inv_context_manager.cache_key, cache_state_uid) # re-compute and store cache if we get invalidate signal @@ -2574,84 +2534,87 @@ class Repository(Base, BaseModel): else: instance = get_instance_cached(*args) - log.debug('Repo instance fetched in %.4fs', inv_context_manager.compute_time) + log.debug("Repo instance fetched in %.4fs", inv_context_manager.compute_time) return instance def _get_instance(self, cache=True, config=None, repo_state_uid=None): - log.debug('Initializing %s instance `%s` with cache flag set to: %s', - self.repo_type, self.repo_path, cache) + log.debug("Initializing %s instance `%s` with cache flag set to: %s", self.repo_type, self.repo_path, cache) config = config or self._config custom_wire = { - 'cache': cache, # controls the vcs.remote cache - 'repo_state_uid': repo_state_uid + "cache": cache, # controls the vcs.remote cache + "repo_state_uid": repo_state_uid, } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) if repo is not None: repo.count() # cache rebuild return repo def get_shadow_repository_path(self, workspace_id): from rhodecode.lib.vcs.backends.base import BaseRepository - shadow_repo_path = BaseRepository._get_shadow_repository_path( - self.repo_full_path, self.repo_id, workspace_id) + + shadow_repo_path = BaseRepository._get_shadow_repository_path(self.repo_full_path, self.repo_id, workspace_id) return shadow_repo_path def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), + UniqueConstraint("group_name", "group_parent_id"), base_table_args, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) _group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) group_name_hash = Column("repo_group_name_hash", String(1024), nullable=False, unique=False) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', cascade="all, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete-orphan") # no cascade, set NULL - scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_group_id==RepoGroup.group_id') + scope_artifacts = relationship("FileStore", primaryjoin="FileStore.scope_repo_group_id==RepoGroup.group_id") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def group_name(self): @@ -2665,9 +2628,10 @@ class RepoGroup(Base, BaseModel): @classmethod def _load_changeset_cache(cls, repo_id, changeset_cache_raw): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not changeset_cache_raw: - dummy['source_repo_id'] = repo_id + dummy["source_repo_id"] = repo_id return json.loads(json.dumps(dummy)) try: @@ -2680,7 +2644,7 @@ class RepoGroup(Base, BaseModel): @hybrid_property def changeset_cache(self): - return self._load_changeset_cache('', self._changeset_cache) + return self._load_changeset_cache("", self._changeset_cache) @changeset_cache.setter def changeset_cache(self, val): @@ -2689,7 +2653,7 @@ class RepoGroup(Base, BaseModel): except Exception: log.error(traceback.format_exc()) - @validates('group_parent_id') + @validates("group_parent_id") def validate_group_parent_id(self, key, val): """ Check cycle references for a parent group to self @@ -2702,6 +2666,7 @@ class RepoGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod @@ -2714,11 +2679,12 @@ class RepoGroup(Base, BaseModel): c = str(ord(c)) chars.append(c) - return ''.join(chars) + return "".join(chars) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2729,12 +2695,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2744,14 +2709,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2760,15 +2723,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user) \ - .order_by(cls.group_id.asc()) \ - .first() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).order_by(cls.group_id.asc()).first() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2793,14 +2751,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2808,13 +2769,14 @@ class RepoGroup(Base, BaseModel): @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @classmethod def _load_commit_change(cls, last_commit_cache): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = last_commit_cache.get('date', empty_date) + date_latest = last_commit_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2846,9 +2808,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2908,8 +2868,7 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def update_commit_cache(self, config=None): @@ -2928,6 +2887,7 @@ class RepoGroup(Base, BaseModel): """ from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) def repo_groups_and_repos(root_gr): @@ -2939,33 +2899,36 @@ class RepoGroup(Base, BaseModel): latest_repo_cs_cache = {} for obj in repo_groups_and_repos(self): repo_cs_cache = obj.changeset_cache - date_latest = latest_repo_cs_cache.get('date', empty_date) - date_current = repo_cs_cache.get('date', empty_date) + date_latest = latest_repo_cs_cache.get("date", empty_date) + date_current = repo_cs_cache.get("date", empty_date) current_timestamp = datetime_to_time(parse_datetime(date_latest)) if current_timestamp < datetime_to_time(parse_datetime(date_current)): latest_repo_cs_cache = repo_cs_cache - if hasattr(obj, 'repo_id'): - latest_repo_cs_cache['source_repo_id'] = obj.repo_id + if hasattr(obj, "repo_id"): + latest_repo_cs_cache["source_repo_id"] = obj.repo_id else: - latest_repo_cs_cache['source_repo_id'] = repo_cs_cache.get('source_repo_id') + latest_repo_cs_cache["source_repo_id"] = repo_cs_cache.get("source_repo_id") - _date_latest = parse_datetime(latest_repo_cs_cache.get('date') or empty_date) + _date_latest = parse_datetime(latest_repo_cs_cache.get("date") or empty_date) - latest_repo_cs_cache['updated_on'] = time.time() + latest_repo_cs_cache["updated_on"] = time.time() self.changeset_cache = latest_repo_cs_cache self.updated_on = _date_latest Session().add(self) Session().commit() - log.debug('updated repo group `%s` with new commit cache %s, and last update_date: %s', - self.group_name, latest_repo_cs_cache, _date_latest) + log.debug( + "updated repo group `%s` with new commit cache %s, and last update_date: %s", + self.group_name, + latest_repo_cs_cache, + _date_latest, + ) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repository groups """ - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: @@ -2989,9 +2952,11 @@ class RepoGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -3021,19 +2986,19 @@ class RepoGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupRepoGroupToPerm.query()\ - .filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -3046,12 +3011,12 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data @@ -3059,124 +3024,112 @@ class RepoGroup(Base, BaseModel): # Since we transformed `group_name` to a hybrid property, we need to # keep compatibility with the code which uses `group_name` field. result = super(RepoGroup, self).get_dict() - result['group_name'] = result.pop('_group_name', None) + result["group_name"] = result.pop("_group_name", None) return result class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), + Index("p_perm_name_idx", "permission_name"), base_table_args, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch, for backward compat we need same value as before so forced pushed - 'branch.push_force', + "branch.push_force", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -3184,9 +3137,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -3194,24 +3145,26 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms(cls, user_id, repo_id=None): - q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ - .join( - Permission, - UserToRepoBranchPermission.permission_id == Permission.permission_id) \ - .join( - UserRepoToPerm, - UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ + q = ( + Session() + .query(UserToRepoBranchPermission, UserRepoToPerm, Permission) + .join(Permission, UserToRepoBranchPermission.permission_id == Permission.permission_id) + .join(UserRepoToPerm, UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) @@ -3219,46 +3172,33 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ - .join( - Permission, - UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ + q = ( + Session() + .query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) + .join(Permission, UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) .join( UserGroupRepoToPerm, - UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id, + ) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) @@ -3266,102 +3206,81 @@ class Permission(Base, BaseModel): @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserRepoGroupToPerm.permission_id == Permission.permission_id)\ - .join( - RepoGroup, - UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - base_table_args - ) + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id", "permission_id"), base_table_args) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -3373,24 +3292,27 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - base_table_args + __tablename__ = "user_user_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "user_group_id", "permission_id"), base_table_args) + + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -3402,43 +3324,52 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - base_table_args - ) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), base_table_args) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - base_table_args + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), base_table_args) + + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') - user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") + user_group_branch_perms = relationship("UserGroupToRepoBranchPermission", cascade="all") @classmethod def create(cls, users_group, repository, permission): @@ -3450,25 +3381,42 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - base_table_args + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + base_table_args, ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None + ) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3480,39 +3428,54 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - base_table_args + UniqueConstraint( + "users_group_id", + "permission_id", + ), + base_table_args, ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - base_table_args + __tablename__ = "user_repo_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "group_id", "permission_id"), base_table_args) + + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3525,20 +3488,28 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - base_table_args + __tablename__ = "users_group_repo_group_to_perm" + __table_args__ = (UniqueConstraint("users_group_id", "group_id"), base_table_args) + + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3550,43 +3521,51 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - base_table_args - ) + __tablename__ = "statistics" + __table_args__ = base_table_args stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - base_table_args + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + base_table_args, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3594,18 +3573,18 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), base_table_args, ) - CACHE_TYPE_FEED = 'FEED' + CACHE_TYPE_FEED = "FEED" # namespaces used to register process/thread aware caches - REPO_INVALIDATION_NAMESPACE = 'repo_cache:{repo_id}' - SETTINGS_INVALIDATION_NAMESPACE = 'system_settings' + REPO_INVALIDATION_NAMESPACE = "repo_cache:{repo_id}" + SETTINGS_INVALIDATION_NAMESPACE = "system_settings" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) @@ -3613,7 +3592,7 @@ class CacheKey(Base, BaseModel): cache_state_uid = Column("cache_state_uid", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args='', cache_state_uid=None): + def __init__(self, cache_key, cache_args="", cache_state_uid=None): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False @@ -3621,9 +3600,7 @@ class CacheKey(Base, BaseModel): self.cache_state_uid = cache_state_uid or self.generate_new_state_uid() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3673,19 +3650,14 @@ class CacheKey(Base, BaseModel): qry = Session().query(cls).filter(cls.cache_args == cache_uid) if delete: qry.delete() - log.debug('cache objects deleted for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects deleted for cache args %s", safe_str(cache_uid)) else: - qry.update({"cache_active": False, - "cache_state_uid": cls.generate_new_state_uid()}) - log.debug('cache objects marked as invalid for cache args %s', - safe_str(cache_uid)) + qry.update({"cache_active": False, "cache_state_uid": cls.generate_new_state_uid()}) + log.debug("cache objects marked as invalid for cache args %s", safe_str(cache_uid)) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for cache args %s', - safe_str(cache_uid)) + log.exception("Cache key invalidation failed for cache args %s", safe_str(cache_uid)) Session().rollback() @classmethod @@ -3697,54 +3669,61 @@ class CacheKey(Base, BaseModel): @classmethod def get_namespace_map(cls, namespace): - return { - x.cache_key: x - for x in cls.query().filter(cls.cache_args == namespace)} + return {x.cache_key: x for x in cls.query().filter(cls.cache_args == namespace)} class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), + Index("cc_revision_idx", "revision"), base_table_args, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - OP_IMMUTABLE = u'immutable' - OP_CHANGEABLE = u'changeable' + OP_IMMUTABLE = "immutable" + OP_CHANGEABLE = "changeable" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) - immutable_state = Column('immutable_state', Unicode(128), nullable=True, default=OP_CHANGEABLE) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) + immutable_state = Column("immutable_state", Unicode(128), nullable=True, default=OP_CHANGEABLE) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') - resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, back_populates="resolved_by") + resolved_by = relationship("ChangesetComment", back_populates="resolved_comment") - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') - history = relationship('ChangesetCommentHistory', cascade='all, delete-orphan', lazy='joined', order_by='ChangesetCommentHistory.version') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") + history = relationship( + "ChangesetCommentHistory", + cascade="all, delete-orphan", + lazy="joined", + order_by="ChangesetCommentHistory.version", + ) @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3755,8 +3734,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3767,7 +3745,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3807,29 +3785,28 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on, - 'comment_resolved_by': self.resolved, - 'comment_commit_id': comment.revision, - 'comment_pull_request_id': comment.pull_request_id, + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, + "comment_resolved_by": self.resolved, + "comment_commit_id": comment.revision, + "comment_pull_request_id": comment.pull_request_id, } return data @@ -3840,27 +3817,31 @@ class ChangesetComment(Base, BaseModel): class ChangesetCommentHistory(Base, BaseModel): - __tablename__ = 'changeset_comments_history' + __tablename__ = "changeset_comments_history" __table_args__ = ( - Index('cch_comment_id_idx', 'comment_id'), + Index("cch_comment_id_idx", "comment_id"), base_table_args, ) - comment_history_id = Column('comment_history_id', Integer(), nullable=False, primary_key=True) - comment_id = Column('comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=False) + comment_history_id = Column("comment_history_id", Integer(), nullable=False, primary_key=True) + comment_id = Column("comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=False) version = Column("version", Integer(), nullable=False, default=0) - created_by_user_id = Column('created_by_user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - deleted = Column('deleted', Boolean(), default=False) + created_by_user_id = Column("created_by_user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + deleted = Column("deleted", Boolean(), default=False) - author = relationship('User', lazy='joined') - comment = relationship('ChangesetComment', cascade="all, delete") + author = relationship("User", lazy="joined") + comment = relationship("ChangesetComment", cascade="all, delete") @classmethod def get_version(cls, comment_id): - q = Session().query(ChangesetCommentHistory).filter( - ChangesetCommentHistory.comment_id == comment_id).order_by(ChangesetCommentHistory.version.desc()) + q = ( + Session() + .query(ChangesetCommentHistory) + .filter(ChangesetCommentHistory.comment_id == comment_id) + .order_by(ChangesetCommentHistory.version.desc()) + ) if q.count() == 0: return 1 elif q.count() >= q[0].version: @@ -3870,18 +3851,18 @@ class ChangesetCommentHistory(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - base_table_args + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + base_table_args, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3890,26 +3871,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3922,8 +3900,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3946,8 +3924,7 @@ class _SetState(object): self._current_state = None def __enter__(self): - log.debug('StateLock: entering set state context of pr %s, setting state to: `%s`', - self._pr, self._pr_state) + log.debug("StateLock: entering set state context of pr %s, setting state to: `%s`", self._pr, self._pr_state) self.set_pr_state(self._pr_state) return self @@ -3957,8 +3934,7 @@ class _SetState(object): return None self.set_pr_state(self._org_state) - log.debug('StateLock: exiting set state context of pr %s, setting state to: `%s`', - self._pr, self._org_state) + log.debug("StateLock: exiting set state context of pr %s, setting state to: `%s`", self._pr, self._org_state) @property def state(self): @@ -3971,7 +3947,7 @@ class _SetState(object): Session().commit() self._current_state = pr_state except Exception: - log.exception('Failed to set PullRequest %s state to %s', self._pr, pr_state) + log.exception("Failed to set PullRequest %s state to %s", self._pr, pr_state) raise @@ -3981,53 +3957,42 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" # available states - STATE_CREATING = u'creating' - STATE_UPDATING = u'updating' - STATE_MERGING = u'merging' - STATE_CREATED = u'created' + STATE_CREATING = "creating" + STATE_UPDATING = "updating" + STATE_MERGING = "merging" + STATE_CREATED = "created" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) - description_renderer = Column('description_renderer', Unicode(64), nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + description_renderer = Column("description_renderer", Unicode(64), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) pull_request_state = Column("pull_request_state", String(255), nullable=True) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) - common_ancestor_id = Column('common_ancestor_id', Unicode(255), nullable=True) + common_ancestor_id = Column("common_ancestor_id", Unicode(255), nullable=True) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _source_ref = Column('org_ref', Unicode(255), nullable=False) + _source_ref = Column("org_ref", Unicode(255), nullable=False) @hybrid_property def source_ref(self): @@ -4035,13 +4000,12 @@ class _PullRequestBase(BaseModel): @source_ref.setter def source_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._source_ref = safe_str(val) - _target_ref = Column('other_ref', Unicode(255), nullable=False) + _target_ref = Column("other_ref", Unicode(255), nullable=False) @hybrid_property def target_ref(self): @@ -4049,37 +4013,32 @@ class _PullRequestBase(BaseModel): @target_ref.setter def target_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._target_ref = safe_str(val) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) last_merge_metadata = Column( - 'last_merge_metadata', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "last_merge_metadata", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) - merge_rev = Column('merge_rev', String(40), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -4089,22 +4048,23 @@ class _PullRequestBase(BaseModel): def work_in_progress(self): """checks if pull request is work in progress by checking the title""" title = self.title.upper() - if re.match(r'^(\[WIP\]\s*|WIP:\s*|WIP\s+)', title): + if re.match(r"^(\[WIP\]\s*|WIP:\s*|WIP\s+)", title): return True return False @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = u':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -4116,13 +4076,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -4130,9 +4088,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -4153,7 +4109,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -4165,7 +4121,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -4174,66 +4130,59 @@ class _PullRequestBase(BaseModel): pull_request = self if with_merge_state: - merge_response, merge_status, msg = \ - PullRequestModel().merge_status(pull_request) + merge_response, merge_status, msg = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status, - 'message': safe_str(msg), + "status": merge_status, + "message": safe_str(msg), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'state': pull_request.pull_request_state, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "state": pull_request.pull_request_state, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data @@ -4254,30 +4203,24 @@ class _PullRequestBase(BaseModel): class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_requests" + __table_args__ = (base_table_args,) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', cascade="all, delete-orphan") - statuses = relationship('ChangesetStatus', cascade="all, delete-orphan") - comments = relationship('ChangesetComment', cascade="all, delete-orphan") - versions = relationship('PullRequestVersion', cascade="all, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -4288,7 +4231,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -4296,15 +4239,13 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @@ -4314,20 +4255,17 @@ class PullRequest(Base, _PullRequestBase): @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data(with_merge_state=False)) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -4347,22 +4285,22 @@ class PullRequest(Base, _PullRequestBase): return self.pull_request_state != PullRequest.STATE_CREATED def __json__(self): - return { - 'revisions': self.revisions, - 'versions': self.versions_count - } + return {"revisions": self.revisions, "versions": self.versions_count} def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): @@ -4382,23 +4320,18 @@ class PullRequest(Base, _PullRequestBase): class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_versions" + __table_args__ = (base_table_args,) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -4423,10 +4356,8 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = (base_table_args,) @hybrid_property def reasons(self): @@ -4438,80 +4369,73 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), + Index("notification_type_idx", "type"), base_table_args, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' - TYPE_PULL_REQUEST_UPDATE = u'pull_request_update' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" + TYPE_PULL_REQUEST_UPDATE = "pull_request_update" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -4543,20 +4467,22 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' - __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - base_table_args + __tablename__ = "user_to_notification" + __table_args__ = (UniqueConstraint("user_id", "notification_id"), base_table_args) + + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) - - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -4564,54 +4490,59 @@ class UserNotification(Base, BaseModel): class UserNotice(Base, BaseModel): - __tablename__ = 'user_notices' - __table_args__ = ( - base_table_args + __tablename__ = "user_notices" + __table_args__ = base_table_args + + NOTIFICATION_TYPE_MESSAGE = "message" + NOTIFICATION_TYPE_NOTICE = "notice" + + NOTIFICATION_LEVEL_INFO = "info" + NOTIFICATION_LEVEL_WARNING = "warning" + NOTIFICATION_LEVEL_ERROR = "error" + + user_notice_id = Column("gist_id", Integer(), primary_key=True) + + notice_subject = Column("notice_subject", Unicode(512), nullable=True) + notice_body = Column("notice_body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + + notice_read = Column("notice_read", Boolean, default=False) + + notification_level = Column("notification_level", String(1024), default=NOTIFICATION_LEVEL_INFO) + notification_type = Column("notification_type", String(1024), default=NOTIFICATION_TYPE_NOTICE) + + notice_created_by = Column("notice_created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + notice_created_on = Column( + "notice_created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now ) - NOTIFICATION_TYPE_MESSAGE = 'message' - NOTIFICATION_TYPE_NOTICE = 'notice' - - NOTIFICATION_LEVEL_INFO = 'info' - NOTIFICATION_LEVEL_WARNING = 'warning' - NOTIFICATION_LEVEL_ERROR = 'error' - - user_notice_id = Column('gist_id', Integer(), primary_key=True) - - notice_subject = Column('notice_subject', Unicode(512), nullable=True) - notice_body = Column('notice_body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - - notice_read = Column('notice_read', Boolean, default=False) - - notification_level = Column('notification_level', String(1024), default=NOTIFICATION_LEVEL_INFO) - notification_type = Column('notification_type', String(1024), default=NOTIFICATION_TYPE_NOTICE) - - notice_created_by = Column('notice_created_by', Integer(), ForeignKey('users.user_id'), nullable=True) - notice_created_on = Column('notice_created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - - user_id = Column('user_id', Integer(), ForeignKey('users.user_id')) - user = relationship('User', lazy="joined", primaryjoin='User.user_id==UserNotice.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id")) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==UserNotice.user_id") @classmethod def create_for_user(cls, user, subject, body, notice_level=NOTIFICATION_LEVEL_INFO, allow_duplicate=False): - - if notice_level not in [cls.NOTIFICATION_LEVEL_ERROR, - cls.NOTIFICATION_LEVEL_WARNING, - cls.NOTIFICATION_LEVEL_INFO]: + if notice_level not in [ + cls.NOTIFICATION_LEVEL_ERROR, + cls.NOTIFICATION_LEVEL_WARNING, + cls.NOTIFICATION_LEVEL_INFO, + ]: return from rhodecode.model.user import UserModel + user = UserModel().get_user(user) new_notice = UserNotice() if not allow_duplicate: - existing_msg = UserNotice().query() \ - .filter(UserNotice.user == user) \ - .filter(UserNotice.notice_body == body) \ - .filter(UserNotice.notice_read == false()) \ + existing_msg = ( + UserNotice() + .query() + .filter(UserNotice.user == user) + .filter(UserNotice.notice_body == body) + .filter(UserNotice.notice_read == false()) .scalar() + ) if existing_msg: - log.warning('Ignoring duplicate notice for user %s', user) + log.warning("Ignoring duplicate notice for user %s", user) return new_notice.user = user @@ -4623,38 +4554,39 @@ class UserNotice(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - base_table_args + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + base_table_args, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -4672,6 +4604,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -4682,8 +4615,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4693,24 +4626,24 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): @@ -4720,27 +4653,26 @@ class Gist(Base, BaseModel): :param kwargs: """ from rhodecode.model.gist import GistModel + full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False, - _vcs_alias=GistModel.vcs_backend) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False, _vcs_alias=GistModel.vcs_backend) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - base_table_args + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + base_table_args, ) - external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): @@ -4788,36 +4720,30 @@ class ExternalIdentity(Base, BaseModel): @classmethod def load_provider_plugin(cls, plugin_id): from rhodecode.authentication.base import loadplugin - _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) + + _plugin_id = "egg:rhodecode-enterprise-ee#{}".format(plugin_id) auth_plugin = loadplugin(_plugin_id) return auth_plugin class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - base_table_args - ) + __tablename__ = "integrations" + __table_args__ = base_table_args - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4825,118 +4751,109 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = base_table_args - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = base_table_args VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules" + __table_args__ = base_table_args - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_pattern(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_pattern(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_pattern(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -4947,37 +4864,37 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - if self.source_branch_pattern.startswith('re:'): + if self.source_branch_pattern.startswith("re:"): source_pattern = self.source_branch_pattern[3:] else: - source_pattern = '^' + glob2re(self.source_branch_pattern) + '$' + source_pattern = "^" + glob2re(self.source_branch_pattern) + "$" source_branch_regex = re.compile(source_pattern) source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - if self.target_branch_pattern.startswith('re:'): + if self.target_branch_pattern.startswith("re:"): target_pattern = self.target_branch_pattern[3:] else: - target_pattern = '^' + glob2re(self.target_branch_pattern) + '$' + target_pattern = "^" + glob2re(self.target_branch_pattern) + "$" target_branch_regex = re.compile(target_pattern) target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False - if self.file_pattern.startswith('re:'): + if self.file_pattern.startswith("re:"): file_pattern = self.file_pattern[3:] else: file_pattern = glob2re(self.file_pattern) @@ -4991,7 +4908,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4999,17 +4916,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -5021,16 +4938,15 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def user_group_vote_rule(self, user_id): - rules = [] if not self.rule_user_groups: return rules @@ -5042,39 +4958,45 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), base_table_args, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -5083,8 +5005,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -5105,8 +5026,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -5124,6 +5044,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -5142,7 +5063,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -5162,16 +5083,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -5183,19 +5103,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -5206,86 +5126,112 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class UserBookmark(Base, BaseModel): - __tablename__ = 'user_bookmarks' + __tablename__ = "user_bookmarks" __table_args__ = ( - UniqueConstraint('user_id', 'bookmark_repo_id'), - UniqueConstraint('user_id', 'bookmark_repo_group_id'), - UniqueConstraint('user_id', 'bookmark_position'), - base_table_args + UniqueConstraint("user_id", "bookmark_repo_id"), + UniqueConstraint("user_id", "bookmark_repo_group_id"), + UniqueConstraint("user_id", "bookmark_position"), + base_table_args, ) - user_bookmark_id = Column("user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user_bookmark_id = Column( + "user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) position = Column("bookmark_position", Integer(), nullable=False) title = Column("bookmark_title", String(255), nullable=True, unique=None, default=None) redirect_url = Column("bookmark_redirect_url", String(10240), nullable=True, unique=None, default=None) created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - bookmark_repo_id = Column("bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) - bookmark_repo_group_id = Column("bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None) + bookmark_repo_id = Column( + "bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + bookmark_repo_group_id = Column( + "bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) user = relationship("User") @@ -5294,95 +5240,112 @@ class UserBookmark(Base, BaseModel): @classmethod def get_by_position_for_user(cls, position, user_id): - return cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .filter(UserBookmark.position == position).scalar() + return cls.query().filter(UserBookmark.user_id == user_id).filter(UserBookmark.position == position).scalar() @classmethod def get_bookmarks_for_user(cls, user_id, cache=True): - bookmarks = cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .options(joinedload(UserBookmark.repository)) \ - .options(joinedload(UserBookmark.repository_group)) \ + bookmarks = ( + cls.query() + .filter(UserBookmark.user_id == user_id) + .options(joinedload(UserBookmark.repository)) + .options(joinedload(UserBookmark.repository_group)) .order_by(UserBookmark.position.asc()) + ) if cache: - bookmarks = bookmarks.options( - FromCache("sql_cache_short", "get_user_{}_bookmarks".format(user_id)) - ) + bookmarks = bookmarks.options(FromCache("sql_cache_short", "get_user_{}_bookmarks".format(user_id))) return bookmarks.all() def __unicode__(self): - return u'' % (self.position, self.redirect_url) + return "" % (self.position, self.redirect_url) class FileStore(Base, BaseModel): - __tablename__ = 'file_store' - __table_args__ = ( - base_table_args - ) + __tablename__ = "file_store" + __table_args__ = base_table_args - file_store_id = Column('file_store_id', Integer(), primary_key=True) - file_uid = Column('file_uid', String(1024), nullable=False) - file_display_name = Column('file_display_name', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), nullable=True) - file_description = Column('file_description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - file_org_name = Column('file_org_name', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=False) + file_store_id = Column("file_store_id", Integer(), primary_key=True) + file_uid = Column("file_uid", String(1024), nullable=False) + file_display_name = Column( + "file_display_name", UnicodeText().with_variant(UnicodeText(2048), "mysql"), nullable=True + ) + file_description = Column( + "file_description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True + ) + file_org_name = Column("file_org_name", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=False) # sha256 hash - file_hash = Column('file_hash', String(512), nullable=False) - file_size = Column('file_size', BigInteger(), nullable=False) + file_hash = Column("file_hash", String(512), nullable=False) + file_size = Column("file_size", BigInteger(), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True) - accessed_count = Column('accessed_count', Integer(), default=0) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True) + accessed_count = Column("accessed_count", Integer(), default=0) - enabled = Column('enabled', Boolean(), nullable=False, default=True) + enabled = Column("enabled", Boolean(), nullable=False, default=True) # if repo/repo_group reference is set, check for permissions - check_acl = Column('check_acl', Boolean(), nullable=False, default=True) + check_acl = Column("check_acl", Boolean(), nullable=False, default=True) # hidden defines an attachment that should be hidden from showing in artifact listing - hidden = Column('hidden', Boolean(), nullable=False, default=False) + hidden = Column("hidden", Boolean(), nullable=False, default=False) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - upload_user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + upload_user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.user_id") - file_metadata = relationship('FileStoreMetadata', lazy='joined') + file_metadata = relationship("FileStoreMetadata", lazy="joined") # scope limited to user, which requester have access to scope_user_id = Column( - 'scope_user_id', Integer(), ForeignKey('users.user_id'), - nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.scope_user_id') + "scope_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.scope_user_id") # scope limited to user group, which requester have access to scope_user_group_id = Column( - 'scope_user_group_id', Integer(), ForeignKey('users_groups.users_group_id'), - nullable=True, unique=None, default=None) - user_group = relationship('UserGroup', lazy='joined') + "scope_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=True, + unique=None, + default=None, + ) + user_group = relationship("UserGroup", lazy="joined") # scope limited to repo, which requester have access to scope_repo_id = Column( - 'scope_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + "scope_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + repo = relationship("Repository", lazy="joined") # scope limited to repo group, which requester have access to scope_repo_group_id = Column( - 'scope_repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "scope_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @classmethod def get_by_store_uid(cls, file_store_uid): return FileStore.query().filter(FileStore.file_uid == file_store_uid).scalar() @classmethod - def create(cls, file_uid, filename, file_hash, file_size, file_display_name='', - file_description='', enabled=True, hidden=False, check_acl=True, - user_id=None, scope_user_id=None, scope_repo_id=None, scope_repo_group_id=None): - + def create( + cls, + file_uid, + filename, + file_hash, + file_size, + file_display_name="", + file_description="", + enabled=True, + hidden=False, + check_acl=True, + user_id=None, + scope_user_id=None, + scope_repo_id=None, + scope_repo_group_id=None, + ): store_entry = FileStore() store_entry.file_uid = file_uid store_entry.file_display_name = file_display_name @@ -5409,14 +5372,16 @@ class FileStore(Base, BaseModel): return for section, key, value, value_type in args: - has_key = FileStoreMetadata().query() \ - .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) \ - .filter(FileStoreMetadata.file_store_meta_section == section) \ - .filter(FileStoreMetadata.file_store_meta_key == key) \ + has_key = ( + FileStoreMetadata() + .query() + .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) + .filter(FileStoreMetadata.file_store_meta_section == section) + .filter(FileStoreMetadata.file_store_meta_key == key) .scalar() + ) if has_key: - msg = 'key `{}` already defined under section `{}` for this file.'\ - .format(key, section) + msg = "key `{}` already defined under section `{}` for this file.".format(key, section) raise ArtifactMetadataDuplicate(msg, err_section=section, err_key=key) # NOTE(marcink): raises ArtifactMetadataBadValueType @@ -5436,86 +5401,99 @@ class FileStore(Base, BaseModel): Session().commit() except IntegrityError: Session().rollback() - raise ArtifactMetadataDuplicate('Duplicate section/key found for this file.') + raise ArtifactMetadataDuplicate("Duplicate section/key found for this file.") @classmethod def bump_access_counter(cls, file_uid, commit=True): - FileStore().query()\ - .filter(FileStore.file_uid == file_uid)\ - .update({FileStore.accessed_count: (FileStore.accessed_count + 1), - FileStore.accessed_on: datetime.datetime.now()}) + FileStore().query().filter(FileStore.file_uid == file_uid).update( + {FileStore.accessed_count: (FileStore.accessed_count + 1), FileStore.accessed_on: datetime.datetime.now()} + ) if commit: Session().commit() def __json__(self): data = { - 'filename': self.file_display_name, - 'filename_org': self.file_org_name, - 'file_uid': self.file_uid, - 'description': self.file_description, - 'hidden': self.hidden, - 'size': self.file_size, - 'created_on': self.created_on, - 'uploaded_by': self.upload_user.get_api_data(details='basic'), - 'downloaded_times': self.accessed_count, - 'sha256': self.file_hash, - 'metadata': self.file_metadata, + "filename": self.file_display_name, + "filename_org": self.file_org_name, + "file_uid": self.file_uid, + "description": self.file_description, + "hidden": self.hidden, + "size": self.file_size, + "created_on": self.created_on, + "uploaded_by": self.upload_user.get_api_data(details="basic"), + "downloaded_times": self.accessed_count, + "sha256": self.file_hash, + "metadata": self.file_metadata, } return data def __repr__(self): - return ''.format(self.file_store_id) + return "".format(self.file_store_id) class FileStoreMetadata(Base, BaseModel): - __tablename__ = 'file_store_metadata' + __tablename__ = "file_store_metadata" __table_args__ = ( - UniqueConstraint('file_store_id', 'file_store_meta_section_hash', 'file_store_meta_key_hash'), - Index('file_store_meta_section_idx', 'file_store_meta_section', mysql_length=255), - Index('file_store_meta_key_idx', 'file_store_meta_key', mysql_length=255), - base_table_args + UniqueConstraint("file_store_id", "file_store_meta_section_hash", "file_store_meta_key_hash"), + Index("file_store_meta_section_idx", "file_store_meta_section", mysql_length=255), + Index("file_store_meta_key_idx", "file_store_meta_key", mysql_length=255), + base_table_args, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } file_store_meta_id = Column( - "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) + "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) _file_store_meta_section = Column( - "file_store_meta_section", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_section", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_section_hash = Column( - "file_store_meta_section_hash", String(255), - nullable=True, unique=None, default=None) + "file_store_meta_section_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_key = Column( - "file_store_meta_key", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_key", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_key_hash = Column( - "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None) + "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_value = Column( - "file_store_meta_value", UnicodeText().with_variant(UnicodeText(20480), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_value", + UnicodeText().with_variant(UnicodeText(20480), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_value_type = Column( - "file_store_meta_value_type", String(255), nullable=True, unique=None, - default='unicode') + "file_store_meta_value_type", String(255), nullable=True, unique=None, default="unicode" + ) file_store_id = Column( - 'file_store_id', Integer(), ForeignKey('file_store.file_store_id'), - nullable=True, unique=None, default=None) + "file_store_id", Integer(), ForeignKey("file_store.file_store_id"), nullable=True, unique=None, default=None + ) - file_store = relationship('FileStore', lazy='joined') + file_store = relationship("FileStore", lazy="joined") @classmethod def valid_value_type(cls, value): - if value.split('.')[0] not in cls.SETTINGS_TYPES: + if value.split(".")[0] not in cls.SETTINGS_TYPES: raise ArtifactMetadataBadValueType( - 'value_type must be one of %s got %s' % (cls.SETTINGS_TYPES.keys(), value)) + "value_type must be one of %s got %s" % (cls.SETTINGS_TYPES.keys(), value) + ) @hybrid_property def file_store_meta_section(self): @@ -5541,13 +5519,13 @@ class FileStoreMetadata(Base, BaseModel): if self._file_store_meta_value_type: # e.g unicode.encrypted == unicode - _type = self._file_store_meta_value_type.split('.')[0] + _type = self._file_store_meta_value_type.split(".")[0] # decode the encrypted value if it's encrypted field type - if '.encrypted' in self._file_store_meta_value_type: + if ".encrypted" in self._file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_result_value(val, None)) # do final type conversion - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] val = converter(val) return val @@ -5556,7 +5534,7 @@ class FileStoreMetadata(Base, BaseModel): def file_store_meta_value(self, val): val = safe_str(val) # encode the encrypted value - if '.encrypted' in self.file_store_meta_value_type: + if ".encrypted" in self.file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._file_store_meta_value = val @@ -5573,28 +5551,30 @@ class FileStoreMetadata(Base, BaseModel): def __json__(self): data = { - 'artifact': self.file_store.file_uid, - 'section': self.file_store_meta_section, - 'key': self.file_store_meta_key, - 'value': self.file_store_meta_value, + "artifact": self.file_store.file_uid, + "section": self.file_store_meta_section, + "key": self.file_store_meta_key, + "value": self.file_store_meta_value, } return data def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.file_store_meta_section, - self.file_store_meta_key, self.file_store_meta_value) + return "<%s[%s]%s=>%s]>" % ( + self.__class__.__name__, + self.file_store_meta_section, + self.file_store_meta_key, + self.file_store_meta_value, + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_migrate_version" + __table_args__ = (base_table_args,) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) @classmethod def set_version(cls, version): @@ -5607,16 +5587,14 @@ class DbMigrateVersion(Base, BaseModel): class DbSession(Base, BaseModel): - __tablename__ = 'db_session' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_session" + __table_args__ = (base_table_args,) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_20_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_20_0_0.py index 081650ae..c02ebe41 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_20_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_20_0_0.py @@ -35,14 +35,34 @@ import traceback import collections from sqlalchemy import ( - or_, and_, not_, func, cast, TypeDecorator, event, - Index, Sequence, UniqueConstraint, ForeignKey, CheckConstraint, Column, - Boolean, String, Unicode, UnicodeText, DateTime, Integer, LargeBinary, - Text, Float, PickleType, BigInteger) + or_, + and_, + not_, + func, + cast, + TypeDecorator, + event, + Index, + Sequence, + UniqueConstraint, + ForeignKey, + CheckConstraint, + Column, + Boolean, + String, + Unicode, + UnicodeText, + DateTime, + Integer, + LargeBinary, + Text, + Float, + PickleType, + BigInteger, +) from sqlalchemy.sql.expression import true, false, case from sqlalchemy.sql.functions import coalesce, count # pragma: no cover -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.exc import IntegrityError # pragma: no cover @@ -55,20 +75,30 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance, VCSError from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, sha1_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri, datetime_to_time) -from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, \ - JsonRaw + str2bool, + safe_str, + get_commit_safe, + sha1_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, + datetime_to_time, +) +from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType, JsonRaw from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher, validate_and_decrypt_data from rhodecode.lib.encrypt2 import Encryptor -from rhodecode.lib.exceptions import ( - ArtifactMetadataDuplicate, ArtifactMetadataBadValueType) +from rhodecode.lib.exceptions import ArtifactMetadataDuplicate, ArtifactMetadataBadValueType from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -83,10 +113,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -98,13 +128,13 @@ def display_user_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') - extra_sort_num = '1' # default + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") + extra_sort_num = "1" # default # NOTE(dan): inactive duplicates goes last - if getattr(obj, 'duplicate_perm', None): - extra_sort_num = '9' + if getattr(obj, "duplicate_perm", None): + extra_sort_num = "9" return prefix + extra_sort_num + obj.username @@ -115,7 +145,7 @@ def display_user_group_sort(obj): of all other resources """ - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.users_group_name @@ -139,18 +169,16 @@ def in_filter_generator(qry, items, limit=500): parts = [] for chunk in range(0, len(items), limit): - parts.append( - qry.in_(items[chunk: chunk + limit]) - ) + parts.append(qry.in_(items[chunk : chunk + limit])) return parts base_table_args = { - 'extend_existing': True, - 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', - 'sqlite_autoincrement': True + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, } @@ -163,6 +191,7 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): @@ -170,23 +199,21 @@ class EncryptedTextValue(TypeDecorator): Setter for storing value """ import rhodecode + if not value: return value # protect against double encrypting if values is already encrypted - if value.startswith('enc$aes$') \ - or value.startswith('enc$aes_hmac$') \ - or value.startswith('enc2$'): - raise ValueError('value needs to be in unencrypted format, ' - 'ie. not starting with enc$ or enc2$') + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$") or value.startswith("enc2$"): + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$ or enc2$") - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - if algo == 'aes': - return 'enc$aes_hmac$%s' % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) - elif algo == 'fernet': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + if algo == "aes": + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).encrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) def process_result_value(self, value, dialect): """ @@ -194,17 +221,18 @@ class EncryptedTextValue(TypeDecorator): """ import rhodecode + if not value: return value - algo = rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' - enc_strict_mode = str2bool(rhodecode.CONFIG.get('rhodecode.encrypted_values.strict') or True) - if algo == 'aes': + algo = rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) + if algo == "aes": decrypted_data = validate_and_decrypt_data(value, ENCRYPTION_KEY, enc_strict_mode) - elif algo == 'fernet': + elif algo == "fernet": return Encryptor(ENCRYPTION_KEY).decrypt(value) else: - ValueError('Bad encryption algorithm, should be fernet or aes, got: {}'.format(algo)) + ValueError("Bad encryption algorithm, should be fernet or aes, got: {}".format(algo)) return decrypted_data @@ -215,20 +243,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -239,11 +267,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" lst = [] for k in self._get_keys(): - lst.append((k, getattr(self, k),)) + lst.append( + ( + k, + getattr(self, k), + ) + ) return lst def populate_obj(self, populate_dict): @@ -300,48 +333,47 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' - __table_args__ = ( - UniqueConstraint('app_settings_name'), - base_table_args - ) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), base_table_args) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -351,14 +383,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -370,7 +401,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -381,40 +412,35 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val @classmethod def get_by_prefix(cls, prefix): - return RhodeCodeSetting.query()\ - .filter(RhodeCodeSetting.app_settings_name.startswith(prefix))\ - .all() + return RhodeCodeSetting.query().filter(RhodeCodeSetting.app_settings_name.startswith(prefix)).all() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' - __table_args__ = ( - UniqueConstraint('ui_key'), - base_table_args - ) + __tablename__ = "rhodecode_ui" + __table_args__ = (UniqueConstraint("ui_key"), base_table_args) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" HOOKS_BUILTIN = [ HOOK_PRE_PULL, @@ -429,60 +455,41 @@ class RhodeCodeUi(Base, BaseModel): # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - base_table_args + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -492,7 +499,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -512,62 +519,60 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - base_table_args + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + base_table_args, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - base_table_args + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + base_table_args, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -578,65 +583,75 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all, delete-orphan') + user_log = relationship("UserLog") + user_perms = relationship( + "UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all, delete-orphan" + ) - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all, delete-orphan') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all, delete-orphan') + repo_to_perm = relationship( + "UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all, delete-orphan" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities external_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) # review rules - user_review_rules = relationship('RepoReviewRuleUser', cascade='all') + user_review_rules = relationship("RepoReviewRuleUser", cascade="all") # artifacts owned - artifacts = relationship('FileStore', primaryjoin='FileStore.user_id==User.user_id') + artifacts = relationship("FileStore", primaryjoin="FileStore.user_id==User.user_id") # no cascade, set NULL - scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_user_id==User.user_id') + scope_artifacts = relationship("FileStore", primaryjoin="FileStore.scope_user_id==User.user_id") def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -649,6 +664,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -656,6 +672,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -665,11 +682,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -682,10 +701,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -694,20 +715,13 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] def emails_cached(self): - emails = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) + emails = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()) - emails = emails.options( - FromCache("sql_cache_short", "get_user_{}_emails".format(self.user_id)) - ) + emails = emails.options(FromCache("sql_cache_short", "get_user_{}_emails".format(self.user_id))) return [self.email] + [x.email for x in emails] @@ -717,44 +731,43 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @LazyProperty def feed_token(self): return self.get_feed_token() def get_feed_token(self, cache=True): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED) + ) if cache: - feed_tokens = feed_tokens.options( - FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) + feed_tokens = feed_tokens.options(FromCache("sql_cache_short", "get_user_feed_token_%s" % self.user_id)) feed_tokens = feed_tokens.all() if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @LazyProperty def artifact_token(self): return self.get_artifact_token() def get_artifact_token(self, cache=True): - artifacts_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ + artifacts_tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == self) .filter(UserApiKeys.role == UserApiKeys.ROLE_ARTIFACT_DOWNLOAD) + ) if cache: artifacts_tokens = artifacts_tokens.options( - FromCache("sql_cache_short", "get_user_artifact_token_%s" % self.user_id)) + FromCache("sql_cache_short", "get_user_artifact_token_%s" % self.user_id) + ) artifacts_tokens = artifacts_tokens.all() if artifacts_tokens: return artifacts_tokens[0].api_key - return 'NO_ARTIFACT_TOKEN_AVAILABLE' + return "NO_ARTIFACT_TOKEN_AVAILABLE" @classmethod def get(cls, user_id, cache=False): @@ -763,34 +776,34 @@ class User(Base, BaseModel): user = cls.query() if cache: - user = user.options( - FromCache("sql_cache_short", "get_users_%s" % user_id)) + user = user.options(FromCache("sql_cache_short", "get_users_%s" % user_id)) return user.get(user_id) @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -803,8 +816,10 @@ class User(Base, BaseModel): else: plain_token_map[token.api_key] = token log.debug( - 'Found %s plain and %s encrypted tokens to check for authentication for this user', - len(plain_token_map), len(enc_token_map)) + "Found %s plain and %s encrypted tokens to check for authentication for this user", + len(plain_token_map), + len(enc_token_map), + ) # plain token match comes first match = plain_token_map.get(auth_token) @@ -818,16 +833,18 @@ class User(Base, BaseModel): break if match: - log.debug('Found matching token %s', match) + log.debug("Found matching token %s", match) if match.repo_id: - log.debug('Found scope, checking for scope match of token %s', match) + log.debug("Found scope, checking for scope match of token %s", match) if match.repo_id == scope_repo_id: return True else: log.debug( - 'AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - match.repo, scope_repo_id) + "AUTH_TOKEN: scope mismatch, token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + match.repo, + scope_repo_id, + ) return False else: return True @@ -841,29 +858,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -871,13 +887,14 @@ class User(Base, BaseModel): @property def language(self): - return self.user_data.get('language') + return self.user_data.get("language") def AuthUser(self, **kwargs): """ Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username, **kwargs) @hybrid_property @@ -893,44 +910,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -938,7 +952,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -947,8 +960,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -960,9 +972,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -974,6 +985,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -992,13 +1004,13 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with %s', kwargs) + log.debug("updated userdata with %s", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -1008,13 +1020,10 @@ class User(Base, BaseModel): @classmethod def get_first_super_admin(cls): - user = User.query()\ - .filter(User.admin == true()) \ - .order_by(User.user_id.asc()) \ - .first() + user = User.query().filter(User.admin == true()).order_by(User.user_id.asc()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -1042,7 +1051,7 @@ class User(Base, BaseModel): def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -1054,16 +1063,18 @@ class User(Base, BaseModel): @classmethod def get_default_user_id(cls): import rhodecode - return rhodecode.CONFIG['default_user_id'] - def _get_default_perms(self, user, suffix=''): + return rhodecode.CONFIG["default_user_id"] + + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -1077,101 +1088,93 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'description': user.description, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "description": user.description, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - base_table_args + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + base_table_args, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_HTTP = 'token_role_http' - ROLE_FEED = 'token_role_feed' - ROLE_ARTIFACT_DOWNLOAD = 'role_artifact_download' + ROLE_ALL = "token_role_all" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_HTTP = "token_role_http" + ROLE_FEED = "token_role_feed" + ROLE_ARTIFACT_DOWNLOAD = "role_artifact_download" # The last one is ignored in the list as we only # use it for one action, and cannot be created by users - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_VCS, ROLE_API, ROLE_HTTP, ROLE_FEED, ROLE_ARTIFACT_DOWNLOAD] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1179,12 +1182,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1196,28 +1200,32 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), - cls.ROLE_ARTIFACT_DOWNLOAD: _('artifacts downloads'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), + cls.ROLE_ARTIFACT_DOWNLOAD: _("artifacts downloads"), }.get(role, role) @classmethod def _get_role_description(cls, role): return { - cls.ROLE_ALL: _('Token for all actions.'), - cls.ROLE_HTTP: _('Token to access RhodeCode pages via web interface without ' - 'login using `api_access_controllers_whitelist` functionality.'), - cls.ROLE_VCS: _('Token to interact over git/hg/svn protocols. ' - 'Requires auth_token authentication plugin to be active.
' - 'Such Token should be used then instead of a password to ' - 'interact with a repository, and additionally can be ' - 'limited to single repository using repo scope.'), - cls.ROLE_API: _('Token limited to api calls.'), - cls.ROLE_FEED: _('Token to read RSS/ATOM feed.'), - cls.ROLE_ARTIFACT_DOWNLOAD: _('Token for artifacts downloads.'), + cls.ROLE_ALL: _("Token for all actions."), + cls.ROLE_HTTP: _( + "Token to access RhodeCode pages via web interface without " + "login using `api_access_controllers_whitelist` functionality." + ), + cls.ROLE_VCS: _( + "Token to interact over git/hg/svn protocols. " + "Requires auth_token authentication plugin to be active.
" + "Such Token should be used then instead of a password to " + "interact with a repository, and additionally can be " + "limited to single repository using repo scope." + ), + cls.ROLE_API: _("Token limited to api calls."), + cls.ROLE_FEED: _("Token to read RSS/ATOM feed."), + cls.ROLE_ARTIFACT_DOWNLOAD: _("Token for artifacts downloads."), }.get(role, role) @property @@ -1226,10 +1234,10 @@ class UserApiKeys(Base, BaseModel): def _get_scope(self): if self.repo: - return 'Repository: {}'.format(self.repo.repo_name) + return "Repository: {}".format(self.repo.repo_name) if self.repo_group: - return 'RepositoryGroup: {} (recursive)'.format(self.repo_group.group_name) - return 'Global' + return "RepositoryGroup: {} (recursive)".format(self.repo_group.group_name) + return "Global" @property def scope_humanized(self): @@ -1242,25 +1250,20 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' - __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - base_table_args - ) - + __tablename__ = "user_email_map" + __table_args__ = (Index("uem_email_idx", "email"), UniqueConstraint("email"), base_table_args) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1273,23 +1276,20 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' - __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - base_table_args - ) - + __tablename__ = "user_ip_map" + __table_args__ = (UniqueConstraint("user_id", "ip_addr"), base_table_args) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1299,43 +1299,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - - UniqueConstraint('ssh_key_fingerprint'), - - base_table_args + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + base_table_args, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1345,41 +1341,47 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "user_logs" + __table_args__ = (base_table_args,) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id',ondelete='SET NULL'), nullable=True, unique=None, default=None) + user_id = Column( + "user_id", Integer(), ForeignKey("users.user_id", ondelete="SET NULL"), nullable=True, unique=None, default=None + ) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id', ondelete='SET NULL'), nullable=True, unique=None, default=None) + repository_id = Column( + "repository_id", + Integer(), + ForeignKey("repositories.repo_id", ondelete="SET NULL"), + nullable=True, + unique=None, + default=None, + ) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) + action_data = Column("action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=LONGTEXT())))) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @hybrid_property @@ -1390,34 +1392,38 @@ class UserLog(Base, BaseModel): def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "users_groups" + __table_args__ = (base_table_args,) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user_group_review_rules = relationship('RepoReviewRuleUserGroup', cascade='all') - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user_group_review_rules = relationship("RepoReviewRuleUserGroup", cascade="all") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1432,6 +1438,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.user_group_description) @hybrid_property @@ -1452,29 +1459,24 @@ class UserGroup(Base, BaseModel): @classmethod def _load_sync(cls, group_data): if group_data: - return group_data.get('extern_type') + return group_data.get("extern_type") @property def sync(self): return self._load_sync(self.group_data) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod @@ -1484,16 +1486,14 @@ class UserGroup(Base, BaseModel): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for user groups """ - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: @@ -1517,9 +1517,11 @@ class UserGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1549,29 +1551,30 @@ class UserGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupUserGroupToPerm.query()\ - .filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.user_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.user_group.members] + entry.members = [x.user.get_dict() for x in _user_group.user_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1582,13 +1585,13 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'sync': user_group.sync, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "sync": user_group.sync, + "owner_email": user_group.user.email, } if with_group_members: @@ -1596,193 +1599,169 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' - __table_args__ = ( - base_table_args, + __tablename__ = "users_groups_members" + __table_args__ = (base_table_args,) + + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') - - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field + UniqueConstraint("repository_id", "field_key"), # no-multi field base_table_args, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), + Index("r_repo_name_idx", "repo_name", mysql_length=255), base_table_args, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' - DEFAULT_CLONE_URI_SSH = 'ssh://{sys_user}@{hostname}/{repo}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" + DEFAULT_CLONE_URI_SSH = "ssh://{sys_user}@{hostname}/{repo}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - push_uri = Column( - "push_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - archived = Column( - "archived", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + push_uri = Column("push_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + archived = Column("archived", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.source_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', cascade="all, delete-orphan") + "PullRequest", primaryjoin="PullRequest.target_repo_id==Repository.repo_id", cascade="all, delete-orphan" + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete-orphan") - scoped_tokens = relationship('UserApiKeys', cascade="all") + scoped_tokens = relationship("UserApiKeys", cascade="all") # no cascade, set NULL - artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_id==Repository.repo_id') + artifacts = relationship("FileStore", primaryjoin="FileStore.scope_repo_id==Repository.repo_id") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev], e.g ['branch', 'master'] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @@ -1796,15 +1775,14 @@ class Repository(Base, BaseModel): @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1813,16 +1791,17 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @classmethod def _load_changeset_cache(cls, repo_id, changeset_cache_raw): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not changeset_cache_raw: - dummy['source_repo_id'] = repo_id + dummy["source_repo_id"] = repo_id return json.loads(json.dumps(dummy)) try: @@ -1871,13 +1850,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1909,14 +1887,12 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True, archived=False): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True, archived=False): q = Repository.query() if not archived: @@ -1937,7 +1913,7 @@ class Repository(Base, BaseModel): @property def repo_uid(self): - return '_{}'.format(self.repo_id) + return "_{}".format(self.repo_id) @property def forks(self): @@ -1966,7 +1942,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1984,8 +1960,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -2003,12 +1978,8 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - return CacheKey.query()\ - .filter(CacheKey.cache_args == invalidation_namespace)\ - .order_by(CacheKey.cache_key)\ - .all() + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + return CacheKey.query().filter(CacheKey.cache_args == invalidation_namespace).order_by(CacheKey.cache_key).all() @property def cached_diffs_relative_dir(self): @@ -2017,16 +1988,12 @@ class Repository(Base, BaseModel): used for safe display for users, who shouldn't know the absolute store path """ - return os.path.join( - os.path.dirname(self.repo_name), - self.cached_diffs_dir.split(os.path.sep)[-1]) + return os.path.join(os.path.dirname(self.repo_name), self.cached_diffs_dir.split(os.path.sep)[-1]) @property def cached_diffs_dir(self): path = self.repo_full_path - return os.path.join( - os.path.dirname(path), - '.__shadow_diff_cache_repo_{}'.format(self.repo_id)) + return os.path.join(os.path.dirname(path), ".__shadow_diff_cache_repo_{}".format(self.repo_id)) def cached_diffs(self): diff_cache_dir = self.cached_diffs_dir @@ -2035,10 +2002,8 @@ class Repository(Base, BaseModel): return [] def shadow_repos(self): - shadow_repos_pattern = '.__shadow_repo_{}'.format(self.repo_id) - return [ - x for x in os.listdir(os.path.dirname(self.repo_full_path)) - if x.startswith(shadow_repos_pattern)] + shadow_repos_pattern = ".__shadow_repo_{}".format(self.repo_id) + return [x for x in os.listdir(os.path.dirname(self.repo_full_path)) if x.startswith(shadow_repos_pattern)] def get_new_name(self, repo_name): """ @@ -2055,14 +2020,14 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repositories """ - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: @@ -2088,9 +2053,11 @@ class Repository(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2125,19 +2092,19 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=True): - q = UserGroupRepoToPerm.query()\ - .filter(UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -2159,33 +2126,31 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'push_uri': repo.push_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "push_uri": repo.push_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -2233,7 +2198,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -2246,53 +2211,52 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @classmethod def _load_commit_change(cls, last_commit_cache): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = last_commit_cache.get('date', empty_date) + date_latest = last_commit_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2311,9 +2275,10 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri @property @@ -2321,62 +2286,64 @@ class Repository(Base, BaseModel): push_uri = self.push_uri if push_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(push_uri)) if url_obj.password: - push_uri = url_obj.with_password('*****') + push_uri = url_obj.with_password("*****") return push_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] ssh = False - if 'ssh' in override: + if "ssh" in override: ssh = True - del override['ssh'] + del override["ssh"] # we didn't override our tmpl from **overrides request = get_current_request() if not uri_tmpl: - if hasattr(request, 'call_context') and hasattr(request.call_context, 'rc_config'): + if hasattr(request, "call_context") and hasattr(request.call_context, "rc_config"): rc_config = request.call_context.rc_config else: rc_config = SettingsModel().get_all_settings(cache=True) if ssh: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_ssh_tmpl') or self.DEFAULT_CLONE_URI_SSH + uri_tmpl = rc_config.get("rhodecode_clone_uri_ssh_tmpl") or self.DEFAULT_CLONE_URI_SSH else: - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, - repo_type=self.repo_type, - **override) + return get_clone_url( + request=request, + uri_tmpl=uri_tmpl, + repo_name=self.repo_name, + repo_id=self.repo_id, + repo_type=self.repo_type, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None, maybe_unreachable=False): return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load, - maybe_unreachable=maybe_unreachable) + self.scm_instance(), commit_id, commit_idx, pre_load=pre_load, maybe_unreachable=maybe_unreachable + ) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2386,8 +2353,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2400,7 +2366,7 @@ class Repository(Base, BaseModel): return commit def flush_commit_cache(self): - self.update_commit_cache(cs_cache={'raw_id':'0'}) + self.update_commit_cache(cs_cache={"raw_id": "0"}) self.update_commit_cache() def update_commit_cache(self, cs_cache=None, config=None): @@ -2421,6 +2387,7 @@ class Repository(Base, BaseModel): """ from rhodecode.lib.vcs.backends.base import BaseChangeset from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) if cs_cache is None: @@ -2432,8 +2399,7 @@ class Repository(Base, BaseModel): empty = scm_repo is None or scm_repo.is_empty() if not empty: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents", "branch"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents", "branch"]) else: cs_cache = EmptyCommit() @@ -2441,25 +2407,27 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _current_datetime = datetime.datetime.utcnow() - last_change = cs_cache.get('date') or _current_datetime + last_change = cs_cache.get("date") or _current_datetime # we check if last update is newer than the new value # if yes, we use the current timestamp instead. Imagine you get # old commit pushed 1y ago, we'd set last update 1y to ago. last_change_timestamp = datetime_to_time(last_change) current_timestamp = datetime_to_time(last_change) if last_change_timestamp > current_timestamp and not empty: - cs_cache['date'] = _current_datetime + cs_cache["date"] = _current_datetime - _date_latest = parse_datetime(cs_cache.get('date') or empty_date) - cs_cache['updated_on'] = time.time() + _date_latest = parse_datetime(cs_cache.get("date") or empty_date) + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache self.updated_on = last_change Session().add(self) @@ -2471,20 +2439,24 @@ class Repository(Base, BaseModel): else: cs_cache = self.changeset_cache - _date_latest = parse_datetime(cs_cache.get('date') or empty_date) + _date_latest = parse_datetime(cs_cache.get("date") or empty_date) - cs_cache['updated_on'] = time.time() + cs_cache["updated_on"] = time.time() self.changeset_cache = cs_cache self.updated_on = _date_latest Session().add(self) Session().commit() - log.debug('updated repo `%s` with new commit cache %s, and last update_date: %s', - self.repo_name, cs_cache, _date_latest) + log.debug( + "updated repo `%s` with new commit cache %s, and last update_date: %s", + self.repo_name, + cs_cache, + _date_latest, + ) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2500,8 +2472,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2515,19 +2486,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2547,8 +2513,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2560,18 +2525,18 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - vcs_full_cache = kwargs.pop('vcs_full_cache', None) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + vcs_full_cache = kwargs.pop("vcs_full_cache", None) if vcs_full_cache is not None: # allows override global config full_cache = vcs_full_cache else: - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: - log.debug('Initializing pure cached instance for %s', self.repo_path) + log.debug("Initializing pure cached instance for %s", self.repo_path) return self._get_instance_cached() # cache here is sent to the "vcs server" @@ -2580,10 +2545,9 @@ class Repository(Base, BaseModel): def _get_instance_cached(self): from rhodecode.lib import rc_cache - cache_namespace_uid = f'repo_instance.{self.repo_id}' - invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format( - repo_id=self.repo_id) - region = rc_cache.get_or_create_region('cache_repo_longterm', cache_namespace_uid) + cache_namespace_uid = f"repo_instance.{self.repo_id}" + invalidation_namespace = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=self.repo_id) + region = rc_cache.get_or_create_region("cache_repo_longterm", cache_namespace_uid) @region.conditional_cache_on_arguments(namespace=cache_namespace_uid) def get_instance_cached(repo_id, context_id, _cache_state_uid): @@ -2593,10 +2557,10 @@ class Repository(Base, BaseModel): # because each thread of gevent needs it's own not shared connection and cache # we also alter `args` so the cache key is individual for every green thread. inv_context_manager = rc_cache.InvalidationContext( - uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, - thread_scoped=True) + uid=cache_namespace_uid, invalidation_namespace=invalidation_namespace, thread_scoped=True + ) with inv_context_manager as invalidation_context: - cache_state_uid = invalidation_context.cache_data['cache_state_uid'] + cache_state_uid = invalidation_context.cache_data["cache_state_uid"] args = (self.repo_id, inv_context_manager.cache_key, cache_state_uid) # re-compute and store cache if we get invalidate signal @@ -2605,84 +2569,87 @@ class Repository(Base, BaseModel): else: instance = get_instance_cached(*args) - log.debug('Repo instance fetched in %.4fs', inv_context_manager.compute_time) + log.debug("Repo instance fetched in %.4fs", inv_context_manager.compute_time) return instance def _get_instance(self, cache=True, config=None, repo_state_uid=None): - log.debug('Initializing %s instance `%s` with cache flag set to: %s', - self.repo_type, self.repo_path, cache) + log.debug("Initializing %s instance `%s` with cache flag set to: %s", self.repo_type, self.repo_path, cache) config = config or self._config custom_wire = { - 'cache': cache, # controls the vcs.remote cache - 'repo_state_uid': repo_state_uid + "cache": cache, # controls the vcs.remote cache + "repo_state_uid": repo_state_uid, } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) if repo is not None: repo.count() # cache rebuild return repo def get_shadow_repository_path(self, workspace_id): from rhodecode.lib.vcs.backends.base import BaseRepository - shadow_repo_path = BaseRepository._get_shadow_repository_path( - self.repo_full_path, self.repo_id, workspace_id) + + shadow_repo_path = BaseRepository._get_shadow_repository_path(self.repo_full_path, self.repo_id, workspace_id) return shadow_repo_path def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), + UniqueConstraint("group_name", "group_parent_id"), base_table_args, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) _group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) group_name_hash = Column("repo_group_name_hash", String(1024), nullable=False, unique=False) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', cascade="all, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete-orphan") # no cascade, set NULL - scope_artifacts = relationship('FileStore', primaryjoin='FileStore.scope_repo_group_id==RepoGroup.group_id') + scope_artifacts = relationship("FileStore", primaryjoin="FileStore.scope_repo_group_id==RepoGroup.group_id") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def group_name(self): @@ -2696,9 +2663,10 @@ class RepoGroup(Base, BaseModel): @classmethod def _load_changeset_cache(cls, repo_id, changeset_cache_raw): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not changeset_cache_raw: - dummy['source_repo_id'] = repo_id + dummy["source_repo_id"] = repo_id return json.loads(json.dumps(dummy)) try: @@ -2711,7 +2679,7 @@ class RepoGroup(Base, BaseModel): @hybrid_property def changeset_cache(self): - return self._load_changeset_cache('', self._changeset_cache) + return self._load_changeset_cache("", self._changeset_cache) @changeset_cache.setter def changeset_cache(self, val): @@ -2720,7 +2688,7 @@ class RepoGroup(Base, BaseModel): except Exception: log.error(traceback.format_exc()) - @validates('group_parent_id') + @validates("group_parent_id") def validate_group_parent_id(self, key, val): """ Check cycle references for a parent group to self @@ -2733,6 +2701,7 @@ class RepoGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod @@ -2745,11 +2714,12 @@ class RepoGroup(Base, BaseModel): c = str(ord(c)) chars.append(c) - return ''.join(chars) + return "".join(chars) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2760,12 +2730,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2775,14 +2744,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2791,15 +2758,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user) \ - .order_by(cls.group_id.asc()) \ - .first() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).order_by(cls.group_id.asc()).first() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2824,14 +2786,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2839,13 +2804,14 @@ class RepoGroup(Base, BaseModel): @property def last_commit_cache_update_diff(self): - return time.time() - (safe_int(self.changeset_cache.get('updated_on')) or 0) + return time.time() - (safe_int(self.changeset_cache.get("updated_on")) or 0) @classmethod def _load_commit_change(cls, last_commit_cache): from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) - date_latest = last_commit_cache.get('date', empty_date) + date_latest = last_commit_cache.get("date", empty_date) try: return parse_datetime(date_latest) except Exception: @@ -2877,9 +2843,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2939,8 +2903,7 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def update_commit_cache(self, config=None): @@ -2959,6 +2922,7 @@ class RepoGroup(Base, BaseModel): """ from rhodecode.lib.vcs.utils.helpers import parse_datetime + empty_date = datetime.datetime.fromtimestamp(0) def repo_groups_and_repos(root_gr): @@ -2970,33 +2934,36 @@ class RepoGroup(Base, BaseModel): latest_repo_cs_cache = {} for obj in repo_groups_and_repos(self): repo_cs_cache = obj.changeset_cache - date_latest = latest_repo_cs_cache.get('date', empty_date) - date_current = repo_cs_cache.get('date', empty_date) + date_latest = latest_repo_cs_cache.get("date", empty_date) + date_current = repo_cs_cache.get("date", empty_date) current_timestamp = datetime_to_time(parse_datetime(date_latest)) if current_timestamp < datetime_to_time(parse_datetime(date_current)): latest_repo_cs_cache = repo_cs_cache - if hasattr(obj, 'repo_id'): - latest_repo_cs_cache['source_repo_id'] = obj.repo_id + if hasattr(obj, "repo_id"): + latest_repo_cs_cache["source_repo_id"] = obj.repo_id else: - latest_repo_cs_cache['source_repo_id'] = repo_cs_cache.get('source_repo_id') + latest_repo_cs_cache["source_repo_id"] = repo_cs_cache.get("source_repo_id") - _date_latest = parse_datetime(latest_repo_cs_cache.get('date') or empty_date) + _date_latest = parse_datetime(latest_repo_cs_cache.get("date") or empty_date) - latest_repo_cs_cache['updated_on'] = time.time() + latest_repo_cs_cache["updated_on"] = time.time() self.changeset_cache = latest_repo_cs_cache self.updated_on = _date_latest Session().add(self) Session().commit() - log.debug('updated repo group `%s` with new commit cache %s, and last update_date: %s', - self.group_name, latest_repo_cs_cache, _date_latest) + log.debug( + "updated repo group `%s` with new commit cache %s, and last update_date: %s", + self.group_name, + latest_repo_cs_cache, + _date_latest, + ) - def permissions(self, with_admins=True, with_owner=True, - expand_from_user_groups=False): + def permissions(self, with_admins=True, with_owner=True, expand_from_user_groups=False): """ Permissions for repository groups """ - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: @@ -3020,9 +2987,11 @@ class RepoGroup(Base, BaseModel): super_admin_rows.append(usr) q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -3052,19 +3021,19 @@ class RepoGroup(Base, BaseModel): return super_admin_rows + owner_row + perm_rows + user_groups_rows def permission_user_groups(self, with_members=False): - q = UserGroupRepoGroupToPerm.query()\ - .filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): entry = AttributeDict(_user_group.users_group.get_dict()) entry.permission = _user_group.permission.permission_name if with_members: - entry.members = [x.user.get_dict() - for x in _user_group.users_group.members] + entry.members = [x.user.get_dict() for x in _user_group.users_group.members] perm_rows.append(entry) perm_rows = sorted(perm_rows, key=display_user_group_sort) @@ -3077,12 +3046,12 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data @@ -3090,124 +3059,112 @@ class RepoGroup(Base, BaseModel): # Since we transformed `group_name` to a hybrid property, we need to # keep compatibility with the code which uses `group_name` field. result = super(RepoGroup, self).get_dict() - result['group_name'] = result.pop('_group_name', None) + result["group_name"] = result.pop("_group_name", None) return result class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), + Index("p_perm_name_idx", "permission_name"), base_table_args, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('branch.none', _('Branch no permissions')), - ('branch.merge', _('Branch access by web merge')), - ('branch.push', _('Branch access by push')), - ('branch.push_force', _('Branch access by push with force')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("branch.none", _("Branch no permissions")), + ("branch.merge", _("Branch access by web merge")), + ("branch.push", _("Branch access by push")), + ("branch.push_force", _("Branch access by push with force")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user, created on # system setup DEFAULT_USER_PERMISSIONS = [ # object perms - 'repository.read', - 'group.read', - 'usergroup.read', + "repository.read", + "group.read", + "usergroup.read", # branch, for backward compat we need same value as before so forced pushed - 'branch.push_force', + "branch.push_force", # global - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'branch.none': 0, - 'branch.merge': 1, - 'branch.push': 3, - 'branch.push_force': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "branch.none": 0, + "branch.merge": 1, + "branch.push": 3, + "branch.push_force": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -3215,9 +3172,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -3225,24 +3180,26 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms(cls, user_id, repo_id=None): - q = Session().query(UserToRepoBranchPermission, UserRepoToPerm, Permission) \ - .join( - Permission, - UserToRepoBranchPermission.permission_id == Permission.permission_id) \ - .join( - UserRepoToPerm, - UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) \ + q = ( + Session() + .query(UserToRepoBranchPermission, UserRepoToPerm, Permission) + .join(Permission, UserToRepoBranchPermission.permission_id == Permission.permission_id) + .join(UserRepoToPerm, UserToRepoBranchPermission.rule_to_perm_id == UserRepoToPerm.repo_to_perm_id) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserToRepoBranchPermission.repository_id == repo_id) @@ -3250,46 +3207,33 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_branch_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) \ - .join( - Permission, - UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) \ + q = ( + Session() + .query(UserGroupToRepoBranchPermission, UserGroupRepoToPerm, Permission) + .join(Permission, UserGroupToRepoBranchPermission.permission_id == Permission.permission_id) .join( UserGroupRepoToPerm, - UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id) \ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) \ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) \ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + UserGroupToRepoBranchPermission.rule_to_perm_id == UserGroupRepoToPerm.users_group_to_perm_id, + ) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupToRepoBranchPermission.repository_id == repo_id) @@ -3297,102 +3241,81 @@ class Permission(Base, BaseModel): @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserRepoGroupToPerm.permission_id == Permission.permission_id)\ - .join( - RepoGroup, - UserRepoGroupToPerm.group_id == RepoGroup.group_id)\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - base_table_args - ) + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id", "permission_id"), base_table_args) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") - branch_perm_entry = relationship('UserToRepoBranchPermission', cascade="all, delete-orphan", lazy='joined') + branch_perm_entry = relationship("UserToRepoBranchPermission", cascade="all, delete-orphan", lazy="joined") @classmethod def create(cls, user, repository, permission): @@ -3404,24 +3327,27 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - base_table_args + __tablename__ = "user_user_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "user_group_id", "permission_id"), base_table_args) + + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -3433,43 +3359,52 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - base_table_args - ) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), base_table_args) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' - __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - base_table_args + __tablename__ = "users_group_repo_to_perm" + __table_args__ = (UniqueConstraint("repository_id", "users_group_id", "permission_id"), base_table_args) + + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') - user_group_branch_perms = relationship('UserGroupToRepoBranchPermission', cascade='all') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") + user_group_branch_perms = relationship("UserGroupToRepoBranchPermission", cascade="all") @classmethod def create(cls, users_group, repository, permission): @@ -3481,25 +3416,42 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - base_table_args + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + base_table_args, ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None + ) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -3511,39 +3463,54 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - base_table_args + UniqueConstraint( + "users_group_id", + "permission_id", + ), + base_table_args, ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - base_table_args + __tablename__ = "user_repo_group_to_perm" + __table_args__ = (UniqueConstraint("user_id", "group_id", "permission_id"), base_table_args) + + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -3556,20 +3523,28 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' - __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - base_table_args + __tablename__ = "users_group_repo_group_to_perm" + __table_args__ = (UniqueConstraint("users_group_id", "group_id"), base_table_args) + + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -3581,43 +3556,51 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - base_table_args - ) + __tablename__ = "statistics" + __table_args__ = base_table_args stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - base_table_args + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + base_table_args, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -3625,18 +3608,18 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), base_table_args, ) - CACHE_TYPE_FEED = 'FEED' + CACHE_TYPE_FEED = "FEED" # namespaces used to register process/thread aware caches - REPO_INVALIDATION_NAMESPACE = 'repo_cache:{repo_id}' - SETTINGS_INVALIDATION_NAMESPACE = 'system_settings' + REPO_INVALIDATION_NAMESPACE = "repo_cache:{repo_id}" + SETTINGS_INVALIDATION_NAMESPACE = "system_settings" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) @@ -3644,7 +3627,7 @@ class CacheKey(Base, BaseModel): cache_state_uid = Column("cache_state_uid", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args='', cache_state_uid=None): + def __init__(self, cache_key, cache_args="", cache_state_uid=None): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False @@ -3652,9 +3635,7 @@ class CacheKey(Base, BaseModel): self.cache_state_uid = cache_state_uid or self.generate_new_state_uid() def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3704,19 +3685,14 @@ class CacheKey(Base, BaseModel): qry = Session().query(cls).filter(cls.cache_args == cache_uid) if delete: qry.delete() - log.debug('cache objects deleted for cache args %s', - safe_str(cache_uid)) + log.debug("cache objects deleted for cache args %s", safe_str(cache_uid)) else: - qry.update({"cache_active": False, - "cache_state_uid": cls.generate_new_state_uid()}) - log.debug('cache objects marked as invalid for cache args %s', - safe_str(cache_uid)) + qry.update({"cache_active": False, "cache_state_uid": cls.generate_new_state_uid()}) + log.debug("cache objects marked as invalid for cache args %s", safe_str(cache_uid)) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for cache args %s', - safe_str(cache_uid)) + log.exception("Cache key invalidation failed for cache args %s", safe_str(cache_uid)) Session().rollback() @classmethod @@ -3728,54 +3704,61 @@ class CacheKey(Base, BaseModel): @classmethod def get_namespace_map(cls, namespace): - return { - x.cache_key: x - for x in cls.query().filter(cls.cache_args == namespace)} + return {x.cache_key: x for x in cls.query().filter(cls.cache_args == namespace)} class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), + Index("cc_revision_idx", "revision"), base_table_args, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - OP_IMMUTABLE = u'immutable' - OP_CHANGEABLE = u'changeable' + OP_IMMUTABLE = "immutable" + OP_CHANGEABLE = "changeable" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) - immutable_state = Column('immutable_state', Unicode(128), nullable=True, default=OP_CHANGEABLE) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) + immutable_state = Column("immutable_state", Unicode(128), nullable=True, default=OP_CHANGEABLE) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, back_populates='resolved_by') - resolved_by = relationship('ChangesetComment', back_populates='resolved_comment') + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, back_populates="resolved_by") + resolved_by = relationship("ChangesetComment", back_populates="resolved_comment") - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') - history = relationship('ChangesetCommentHistory', cascade='all, delete-orphan', lazy='joined', order_by='ChangesetCommentHistory.version') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") + history = relationship( + "ChangesetCommentHistory", + cascade="all, delete-orphan", + lazy="joined", + order_by="ChangesetCommentHistory.version", + ) @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3786,8 +3769,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3850,31 +3832,30 @@ class ChangesetComment(Base, BaseModel): return version def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on, - 'comment_resolved_by': self.resolved, - 'comment_commit_id': comment.revision, - 'comment_pull_request_id': comment.pull_request_id, - 'comment_last_version': self.last_version + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, + "comment_resolved_by": self.resolved, + "comment_commit_id": comment.revision, + "comment_pull_request_id": comment.pull_request_id, + "comment_last_version": self.last_version, } return data @@ -3885,27 +3866,31 @@ class ChangesetComment(Base, BaseModel): class ChangesetCommentHistory(Base, BaseModel): - __tablename__ = 'changeset_comments_history' + __tablename__ = "changeset_comments_history" __table_args__ = ( - Index('cch_comment_id_idx', 'comment_id'), + Index("cch_comment_id_idx", "comment_id"), base_table_args, ) - comment_history_id = Column('comment_history_id', Integer(), nullable=False, primary_key=True) - comment_id = Column('comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=False) + comment_history_id = Column("comment_history_id", Integer(), nullable=False, primary_key=True) + comment_id = Column("comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=False) version = Column("version", Integer(), nullable=False, default=0) - created_by_user_id = Column('created_by_user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - deleted = Column('deleted', Boolean(), default=False) + created_by_user_id = Column("created_by_user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + deleted = Column("deleted", Boolean(), default=False) - author = relationship('User', lazy='joined') - comment = relationship('ChangesetComment', cascade="all, delete") + author = relationship("User", lazy="joined") + comment = relationship("ChangesetComment", cascade="all, delete") @classmethod def get_version(cls, comment_id): - q = Session().query(ChangesetCommentHistory).filter( - ChangesetCommentHistory.comment_id == comment_id).order_by(ChangesetCommentHistory.version.desc()) + q = ( + Session() + .query(ChangesetCommentHistory) + .filter(ChangesetCommentHistory.comment_id == comment_id) + .order_by(ChangesetCommentHistory.version.desc()) + ) if q.count() == 0: return 1 elif q.count() >= q[0].version: @@ -3915,18 +3900,18 @@ class ChangesetCommentHistory(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - base_table_args + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + base_table_args, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3935,26 +3920,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3967,8 +3949,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3991,8 +3973,7 @@ class _SetState(object): self._current_state = None def __enter__(self): - log.debug('StateLock: entering set state context of pr %s, setting state to: `%s`', - self._pr, self._pr_state) + log.debug("StateLock: entering set state context of pr %s, setting state to: `%s`", self._pr, self._pr_state) self.set_pr_state(self._pr_state) return self @@ -4002,8 +3983,7 @@ class _SetState(object): return None self.set_pr_state(self._org_state) - log.debug('StateLock: exiting set state context of pr %s, setting state to: `%s`', - self._pr, self._org_state) + log.debug("StateLock: exiting set state context of pr %s, setting state to: `%s`", self._pr, self._org_state) @property def state(self): @@ -4016,7 +3996,7 @@ class _SetState(object): Session().commit() self._current_state = pr_state except Exception: - log.exception('Failed to set PullRequest %s state to %s', self._pr, pr_state) + log.exception("Failed to set PullRequest %s state to %s", self._pr, pr_state) raise @@ -4026,53 +4006,42 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" # available states - STATE_CREATING = u'creating' - STATE_UPDATING = u'updating' - STATE_MERGING = u'merging' - STATE_CREATED = u'created' + STATE_CREATING = "creating" + STATE_UPDATING = "updating" + STATE_MERGING = "merging" + STATE_CREATED = "created" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) - description_renderer = Column('description_renderer', Unicode(64), nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) + description_renderer = Column("description_renderer", Unicode(64), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) pull_request_state = Column("pull_request_state", String(255), nullable=True) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) - common_ancestor_id = Column('common_ancestor_id', Unicode(255), nullable=True) + common_ancestor_id = Column("common_ancestor_id", Unicode(255), nullable=True) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _source_ref = Column('org_ref', Unicode(255), nullable=False) + _source_ref = Column("org_ref", Unicode(255), nullable=False) @hybrid_property def source_ref(self): @@ -4080,13 +4049,12 @@ class _PullRequestBase(BaseModel): @source_ref.setter def source_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._source_ref = safe_str(val) - _target_ref = Column('other_ref', Unicode(255), nullable=False) + _target_ref = Column("other_ref", Unicode(255), nullable=False) @hybrid_property def target_ref(self): @@ -4094,37 +4062,32 @@ class _PullRequestBase(BaseModel): @target_ref.setter def target_ref(self, val): - parts = (val or '').split(':') + parts = (val or "").split(":") if len(parts) != 3: - raise ValueError( - 'Invalid reference format given: {}, expected X:Y:Z'.format(val)) + raise ValueError("Invalid reference format given: {}, expected X:Y:Z".format(val)) self._target_ref = safe_str(val) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) last_merge_metadata = Column( - 'last_merge_metadata', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "last_merge_metadata", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) - merge_rev = Column('merge_rev', String(40), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -4136,12 +4099,12 @@ class _PullRequestBase(BaseModel): if not self.last_merge_metadata: return metadata - if hasattr(self.last_merge_metadata, 'de_coerce'): + if hasattr(self.last_merge_metadata, "de_coerce"): for k, v in self.last_merge_metadata.de_coerce().items(): - if k in ['target_ref', 'source_ref']: - metadata[k] = Reference(v['type'], v['name'], v['commit_id']) + if k in ["target_ref", "source_ref"]: + metadata[k] = Reference(v["type"], v["name"], v["commit_id"]) else: - if hasattr(v, 'de_coerce'): + if hasattr(v, "de_coerce"): metadata[k] = v.de_coerce() else: metadata[k] = v @@ -4151,22 +4114,23 @@ class _PullRequestBase(BaseModel): def work_in_progress(self): """checks if pull request is work in progress by checking the title""" title = self.title.upper() - if re.match(r'^(\[WIP\]\s*|WIP:\s*|WIP\s+)', title): + if re.match(r"^(\[WIP\]\s*|WIP:\s*|WIP\s+)", title): return True return False @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = u':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -4178,13 +4142,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -4192,9 +4154,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -4215,7 +4175,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -4227,7 +4187,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -4236,66 +4196,59 @@ class _PullRequestBase(BaseModel): pull_request = self if with_merge_state: - merge_response, merge_status, msg = \ - PullRequestModel().merge_status(pull_request) + merge_response, merge_status, msg = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status, - 'message': safe_str(msg), + "status": merge_status, + "message": safe_str(msg), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'state': pull_request.pull_request_state, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "state": pull_request.pull_request_state, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for obj, reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for obj, reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data @@ -4316,30 +4269,24 @@ class _PullRequestBase(BaseModel): class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_requests" + __table_args__ = (base_table_args,) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', cascade="all, delete-orphan") - statuses = relationship('ChangesetStatus', cascade="all, delete-orphan") - comments = relationship('ChangesetComment', cascade="all, delete-orphan") - versions = relationship('PullRequestVersion', cascade="all, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -4350,7 +4297,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -4358,15 +4305,13 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @@ -4376,20 +4321,17 @@ class PullRequest(Base, _PullRequestBase): @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data(with_merge_state=False)) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -4409,22 +4351,22 @@ class PullRequest(Base, _PullRequestBase): return self.pull_request_state != PullRequest.STATE_CREATED def __json__(self): - return { - 'revisions': self.revisions, - 'versions': self.versions_count - } + return {"revisions": self.revisions, "versions": self.versions_count} def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): @@ -4444,23 +4386,18 @@ class PullRequest(Base, _PullRequestBase): class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_versions" + __table_args__ = (base_table_args,) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -4485,10 +4422,8 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "pull_request_reviewers" + __table_args__ = (base_table_args,) @hybrid_property def reasons(self): @@ -4500,80 +4435,73 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") - rule_data = Column( - 'rule_data_json', - JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) def rule_user_group_data(self): """ Returns the voting user group rule data for this reviewer """ - if self.rule_data and 'vote_rule' in self.rule_data: + if self.rule_data and "vote_rule" in self.rule_data: user_group_data = {} - if 'rule_user_group_entry_id' in self.rule_data: + if "rule_user_group_entry_id" in self.rule_data: # means a group with voting rules ! - user_group_data['id'] = self.rule_data['rule_user_group_entry_id'] - user_group_data['name'] = self.rule_data['rule_name'] - user_group_data['vote_rule'] = self.rule_data['vote_rule'] + user_group_data["id"] = self.rule_data["rule_user_group_entry_id"] + user_group_data["name"] = self.rule_data["rule_name"] + user_group_data["vote_rule"] = self.rule_data["vote_rule"] return user_group_data def __unicode__(self): - return u"<%s('id:%s')>" % (self.__class__.__name__, - self.pull_requests_reviewers_id) + return "<%s('id:%s')>" % (self.__class__.__name__, self.pull_requests_reviewers_id) class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), + Index("notification_type_idx", "type"), base_table_args, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' - TYPE_PULL_REQUEST_UPDATE = u'pull_request_update' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" + TYPE_PULL_REQUEST_UPDATE = "pull_request_update" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -4605,20 +4533,22 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' - __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - base_table_args + __tablename__ = "user_to_notification" + __table_args__ = (UniqueConstraint("user_id", "notification_id"), base_table_args) + + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) - - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -4626,54 +4556,59 @@ class UserNotification(Base, BaseModel): class UserNotice(Base, BaseModel): - __tablename__ = 'user_notices' - __table_args__ = ( - base_table_args + __tablename__ = "user_notices" + __table_args__ = base_table_args + + NOTIFICATION_TYPE_MESSAGE = "message" + NOTIFICATION_TYPE_NOTICE = "notice" + + NOTIFICATION_LEVEL_INFO = "info" + NOTIFICATION_LEVEL_WARNING = "warning" + NOTIFICATION_LEVEL_ERROR = "error" + + user_notice_id = Column("gist_id", Integer(), primary_key=True) + + notice_subject = Column("notice_subject", Unicode(512), nullable=True) + notice_body = Column("notice_body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + + notice_read = Column("notice_read", Boolean, default=False) + + notification_level = Column("notification_level", String(1024), default=NOTIFICATION_LEVEL_INFO) + notification_type = Column("notification_type", String(1024), default=NOTIFICATION_TYPE_NOTICE) + + notice_created_by = Column("notice_created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + notice_created_on = Column( + "notice_created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now ) - NOTIFICATION_TYPE_MESSAGE = 'message' - NOTIFICATION_TYPE_NOTICE = 'notice' - - NOTIFICATION_LEVEL_INFO = 'info' - NOTIFICATION_LEVEL_WARNING = 'warning' - NOTIFICATION_LEVEL_ERROR = 'error' - - user_notice_id = Column('gist_id', Integer(), primary_key=True) - - notice_subject = Column('notice_subject', Unicode(512), nullable=True) - notice_body = Column('notice_body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - - notice_read = Column('notice_read', Boolean, default=False) - - notification_level = Column('notification_level', String(1024), default=NOTIFICATION_LEVEL_INFO) - notification_type = Column('notification_type', String(1024), default=NOTIFICATION_TYPE_NOTICE) - - notice_created_by = Column('notice_created_by', Integer(), ForeignKey('users.user_id'), nullable=True) - notice_created_on = Column('notice_created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - - user_id = Column('user_id', Integer(), ForeignKey('users.user_id')) - user = relationship('User', lazy="joined", primaryjoin='User.user_id==UserNotice.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id")) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==UserNotice.user_id") @classmethod def create_for_user(cls, user, subject, body, notice_level=NOTIFICATION_LEVEL_INFO, allow_duplicate=False): - - if notice_level not in [cls.NOTIFICATION_LEVEL_ERROR, - cls.NOTIFICATION_LEVEL_WARNING, - cls.NOTIFICATION_LEVEL_INFO]: + if notice_level not in [ + cls.NOTIFICATION_LEVEL_ERROR, + cls.NOTIFICATION_LEVEL_WARNING, + cls.NOTIFICATION_LEVEL_INFO, + ]: return from rhodecode.model.user import UserModel + user = UserModel().get_user(user) new_notice = UserNotice() if not allow_duplicate: - existing_msg = UserNotice().query() \ - .filter(UserNotice.user == user) \ - .filter(UserNotice.notice_body == body) \ - .filter(UserNotice.notice_read == false()) \ + existing_msg = ( + UserNotice() + .query() + .filter(UserNotice.user == user) + .filter(UserNotice.notice_body == body) + .filter(UserNotice.notice_read == false()) .scalar() + ) if existing_msg: - log.warning('Ignoring duplicate notice for user %s', user) + log.warning("Ignoring duplicate notice for user %s", user) return new_notice.user = user @@ -4685,38 +4620,39 @@ class UserNotice(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - base_table_args + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + base_table_args, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -4734,6 +4670,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -4744,8 +4681,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -4755,24 +4692,24 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): @@ -4782,27 +4719,26 @@ class Gist(Base, BaseModel): :param kwargs: """ from rhodecode.model.gist import GistModel + full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False, - _vcs_alias=GistModel.vcs_backend) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False, _vcs_alias=GistModel.vcs_backend) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - base_table_args + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + base_table_args, ) - external_id = Column('external_id', Unicode(255), default=u'', primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): @@ -4850,36 +4786,30 @@ class ExternalIdentity(Base, BaseModel): @classmethod def load_provider_plugin(cls, plugin_id): from rhodecode.authentication.base import loadplugin - _plugin_id = 'egg:rhodecode-enterprise-ee#{}'.format(plugin_id) + + _plugin_id = "egg:rhodecode-enterprise-ee#{}".format(plugin_id) auth_plugin = loadplugin(_plugin_id) return auth_plugin class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - base_table_args - ) + __tablename__ = "integrations" + __table_args__ = base_table_args - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -4887,118 +4817,109 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users" + __table_args__ = base_table_args - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = base_table_args VOTE_RULE_ALL = -1 - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) vote_rule = Column("vote_rule", Integer(), nullable=True, default=VOTE_RULE_ALL) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory, - 'vote_rule': self.vote_rule - } + return {"mandatory": self.mandatory, "vote_rule": self.vote_rule} @property def vote_rule_label(self): if not self.vote_rule or self.vote_rule == self.VOTE_RULE_ALL: - return 'all must vote' + return "all must vote" else: - return 'min. vote {}'.format(self.vote_rule) + return "min. vote {}".format(self.vote_rule) class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - base_table_args - ) + __tablename__ = "repo_review_rules" + __table_args__ = base_table_args - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - review_rule_name = Column('review_rule_name', String(255)) - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _target_branch_pattern = Column("target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + review_rule_name = Column("review_rule_name", String(255)) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _target_branch_pattern = Column( + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @hybrid_property def source_branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @source_branch_pattern.setter def source_branch_pattern(self, value): self._validate_pattern(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def target_branch_pattern(self): - return self._target_branch_pattern or '*' + return self._target_branch_pattern or "*" @target_branch_pattern.setter def target_branch_pattern(self, value): self._validate_pattern(value) - self._target_branch_pattern = value or '*' + self._target_branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_pattern(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, source_branch, target_branch, files_changed): """ @@ -5009,43 +4930,43 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - source_branch = source_branch or '' - target_branch = target_branch or '' + source_branch = source_branch or "" + target_branch = target_branch or "" files_changed = files_changed or [] branch_matches = True if source_branch or target_branch: - if self.source_branch_pattern == '*': + if self.source_branch_pattern == "*": source_branch_match = True else: - if self.source_branch_pattern.startswith('re:'): + if self.source_branch_pattern.startswith("re:"): source_pattern = self.source_branch_pattern[3:] else: - source_pattern = '^' + glob2re(self.source_branch_pattern) + '$' + source_pattern = "^" + glob2re(self.source_branch_pattern) + "$" source_branch_regex = re.compile(source_pattern) source_branch_match = bool(source_branch_regex.search(source_branch)) - if self.target_branch_pattern == '*': + if self.target_branch_pattern == "*": target_branch_match = True else: - if self.target_branch_pattern.startswith('re:'): + if self.target_branch_pattern.startswith("re:"): target_pattern = self.target_branch_pattern[3:] else: - target_pattern = '^' + glob2re(self.target_branch_pattern) + '$' + target_pattern = "^" + glob2re(self.target_branch_pattern) + "$" target_branch_regex = re.compile(target_pattern) target_branch_match = bool(target_branch_regex.search(target_branch)) branch_matches = source_branch_match and target_branch_match files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False - if self.file_pattern.startswith('re:'): + if self.file_pattern.startswith("re:"): file_pattern = self.file_pattern[3:] else: file_pattern = glob2re(self.file_pattern) file_regex = re.compile(file_pattern) for file_data in files_changed: - filename = file_data.get('filename') + filename = file_data.get("filename") if file_regex.search(filename): files_matches = True @@ -5055,7 +4976,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -5063,17 +4984,17 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'user_group_id': rule_user_group.users_group.users_group_id, - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "user_group_id": rule_user_group.users_group.users_group_id, + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: @@ -5085,16 +5006,15 @@ class RepoReviewRule(Base, BaseModel): continue users[key] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def user_group_vote_rule(self, user_id): - rules = [] if not self.rule_user_groups: return rules @@ -5106,39 +5026,45 @@ class RepoReviewRule(Base, BaseModel): return rules def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class ScheduleEntry(Base, BaseModel): - __tablename__ = 'schedule_entries' + __tablename__ = "schedule_entries" __table_args__ = ( - UniqueConstraint('schedule_name', name='s_schedule_name_idx'), - UniqueConstraint('task_uid', name='s_task_uid_idx'), + UniqueConstraint("schedule_name", name="s_schedule_name_idx"), + UniqueConstraint("task_uid", name="s_task_uid_idx"), base_table_args, ) - schedule_types = ['crontab', 'timedelta', 'integer'] - schedule_entry_id = Column('schedule_entry_id', Integer(), primary_key=True) + schedule_types = ["crontab", "timedelta", "integer"] + schedule_entry_id = Column("schedule_entry_id", Integer(), primary_key=True) schedule_name = Column("schedule_name", String(255), nullable=False, unique=None, default=None) schedule_description = Column("schedule_description", String(10000), nullable=True, unique=None, default=None) schedule_enabled = Column("schedule_enabled", Boolean(), nullable=False, unique=None, default=True) _schedule_type = Column("schedule_type", String(255), nullable=False, unique=None, default=None) - schedule_definition = Column('schedule_definition_json', MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT())))) + schedule_definition = Column( + "schedule_definition_json", + MutationObj.as_mutable(JsonType(default=lambda: "", dialect_map=dict(mysql=LONGTEXT()))), + ) - schedule_last_run = Column('schedule_last_run', DateTime(timezone=False), nullable=True, unique=None, default=None) - schedule_total_run_count = Column('schedule_total_run_count', Integer(), nullable=True, unique=None, default=0) + schedule_last_run = Column("schedule_last_run", DateTime(timezone=False), nullable=True, unique=None, default=None) + schedule_total_run_count = Column("schedule_total_run_count", Integer(), nullable=True, unique=None, default=0) # task task_uid = Column("task_uid", String(255), nullable=False, unique=None, default=None) task_dot_notation = Column("task_dot_notation", String(4096), nullable=False, unique=None, default=None) - task_args = Column('task_args_json', MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT())))) - task_kwargs = Column('task_kwargs_json', MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT())))) + task_args = Column( + "task_args_json", MutationObj.as_mutable(JsonType(default=list, dialect_map=dict(mysql=LONGTEXT()))) + ) + task_kwargs = Column( + "task_kwargs_json", MutationObj.as_mutable(JsonType(default=dict, dialect_map=dict(mysql=LONGTEXT()))) + ) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None, default=None) @hybrid_property def schedule_type(self): @@ -5147,8 +5073,7 @@ class ScheduleEntry(Base, BaseModel): @schedule_type.setter def schedule_type(self, val): if val not in self.schedule_types: - raise ValueError('Value must be on of `{}` and got `{}`'.format( - val, self.schedule_type)) + raise ValueError("Value must be on of `{}` and got `{}`".format(val, self.schedule_type)) self._schedule_type = val @@ -5169,8 +5094,7 @@ class ScheduleEntry(Base, BaseModel): kwargs = dict() dot_notation = obj.task_dot_notation - val = '.'.join(map(safe_str, [ - sorted(dot_notation), args, sorted(kwargs.items())])) + val = ".".join(map(safe_str, [sorted(dot_notation), args, sorted(kwargs.items())])) return hashlib.sha1(val).hexdigest() @classmethod @@ -5188,6 +5112,7 @@ class ScheduleEntry(Base, BaseModel): @property def schedule(self): from rhodecode.lib.celerylib.utils import raw_2_schedule + schedule = raw_2_schedule(self.schedule_definition, self.schedule_type) return schedule @@ -5206,7 +5131,7 @@ class ScheduleEntry(Base, BaseModel): return dict() def _as_raw(self, val): - if hasattr(val, 'de_coerce'): + if hasattr(val, "de_coerce"): val = val.de_coerce() if val: val = json.dumps(val) @@ -5226,16 +5151,15 @@ class ScheduleEntry(Base, BaseModel): return self._as_raw(self.task_kwargs) def __repr__(self): - return ''.format( - self.schedule_entry_id, self.schedule_name) + return "".format(self.schedule_entry_id, self.schedule_name) -@event.listens_for(ScheduleEntry, 'before_update') +@event.listens_for(ScheduleEntry, "before_update") def update_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) -@event.listens_for(ScheduleEntry, 'before_insert') +@event.listens_for(ScheduleEntry, "before_insert") def set_task_uid(mapper, connection, target): target.task_uid = ScheduleEntry.get_uid(target) @@ -5247,19 +5171,19 @@ class _BaseBranchPerms(BaseModel): @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" @hybrid_property def branch_hash(self): return self._branch_hash def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" # set the Hash when setting the branch pattern self._branch_hash = self.compute_hash(self._branch_pattern) @@ -5270,86 +5194,112 @@ class _BaseBranchPerms(BaseModel): :param branch: branch name for the commit """ - branch = branch or '' + branch = branch or "" branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) return branch_matches class UserToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("repo_to_perm.repo_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_repo_to_perm = relationship("UserRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('repo_to_perm.repo_to_perm_id'), nullable=False, unique=None, default=None) - user_repo_to_perm = relationship('UserRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_repo_to_perm, self.branch_pattern) class UserGroupToRepoBranchPermission(Base, _BaseBranchPerms): - __tablename__ = 'user_group_to_repo_branch_permissions' - __table_args__ = ( - base_table_args + __tablename__ = "user_group_to_repo_branch_permissions" + __table_args__ = base_table_args + + branch_rule_id = Column("branch_rule_id", Integer(), primary_key=True) + + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) + repo = relationship("Repository", backref="user_group_branch_perms") - branch_rule_id = Column('branch_rule_id', Integer(), primary_key=True) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + permission = relationship("Permission") - repository_id = Column('repository_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - repo = relationship('Repository', backref='user_group_branch_perms') + rule_to_perm_id = Column( + "rule_to_perm_id", + Integer(), + ForeignKey("users_group_repo_to_perm.users_group_to_perm_id"), + nullable=False, + unique=None, + default=None, + ) + user_group_repo_to_perm = relationship("UserGroupRepoToPerm") - permission_id = Column('permission_id', Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - permission = relationship('Permission') - - rule_to_perm_id = Column('rule_to_perm_id', Integer(), ForeignKey('users_group_repo_to_perm.users_group_to_perm_id'), nullable=False, unique=None, default=None) - user_group_repo_to_perm = relationship('UserGroupRepoToPerm') - - rule_order = Column('rule_order', Integer(), nullable=False) - _branch_pattern = Column('branch_pattern', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), default=u'*') # glob - _branch_hash = Column('branch_hash', UnicodeText().with_variant(UnicodeText(2048), 'mysql')) + rule_order = Column("rule_order", Integer(), nullable=False) + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(2048), "mysql"), default="*" + ) # glob + _branch_hash = Column("branch_hash", UnicodeText().with_variant(UnicodeText(2048), "mysql")) def __unicode__(self): - return u' %r)>' % ( - self.user_group_repo_to_perm, self.branch_pattern) + return " %r)>" % (self.user_group_repo_to_perm, self.branch_pattern) class UserBookmark(Base, BaseModel): - __tablename__ = 'user_bookmarks' + __tablename__ = "user_bookmarks" __table_args__ = ( - UniqueConstraint('user_id', 'bookmark_repo_id'), - UniqueConstraint('user_id', 'bookmark_repo_group_id'), - UniqueConstraint('user_id', 'bookmark_position'), - base_table_args + UniqueConstraint("user_id", "bookmark_repo_id"), + UniqueConstraint("user_id", "bookmark_repo_group_id"), + UniqueConstraint("user_id", "bookmark_position"), + base_table_args, ) - user_bookmark_id = Column("user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + user_bookmark_id = Column( + "user_bookmark_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) position = Column("bookmark_position", Integer(), nullable=False) title = Column("bookmark_title", String(255), nullable=True, unique=None, default=None) redirect_url = Column("bookmark_redirect_url", String(10240), nullable=True, unique=None, default=None) created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - bookmark_repo_id = Column("bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) - bookmark_repo_group_id = Column("bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None) + bookmark_repo_id = Column( + "bookmark_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + bookmark_repo_group_id = Column( + "bookmark_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) user = relationship("User") @@ -5358,95 +5308,112 @@ class UserBookmark(Base, BaseModel): @classmethod def get_by_position_for_user(cls, position, user_id): - return cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .filter(UserBookmark.position == position).scalar() + return cls.query().filter(UserBookmark.user_id == user_id).filter(UserBookmark.position == position).scalar() @classmethod def get_bookmarks_for_user(cls, user_id, cache=True): - bookmarks = cls.query() \ - .filter(UserBookmark.user_id == user_id) \ - .options(joinedload(UserBookmark.repository)) \ - .options(joinedload(UserBookmark.repository_group)) \ + bookmarks = ( + cls.query() + .filter(UserBookmark.user_id == user_id) + .options(joinedload(UserBookmark.repository)) + .options(joinedload(UserBookmark.repository_group)) .order_by(UserBookmark.position.asc()) + ) if cache: - bookmarks = bookmarks.options( - FromCache("sql_cache_short", "get_user_{}_bookmarks".format(user_id)) - ) + bookmarks = bookmarks.options(FromCache("sql_cache_short", "get_user_{}_bookmarks".format(user_id))) return bookmarks.all() def __unicode__(self): - return u'' % (self.position, self.redirect_url) + return "" % (self.position, self.redirect_url) class FileStore(Base, BaseModel): - __tablename__ = 'file_store' - __table_args__ = ( - base_table_args - ) + __tablename__ = "file_store" + __table_args__ = base_table_args - file_store_id = Column('file_store_id', Integer(), primary_key=True) - file_uid = Column('file_uid', String(1024), nullable=False) - file_display_name = Column('file_display_name', UnicodeText().with_variant(UnicodeText(2048), 'mysql'), nullable=True) - file_description = Column('file_description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=True) - file_org_name = Column('file_org_name', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), nullable=False) + file_store_id = Column("file_store_id", Integer(), primary_key=True) + file_uid = Column("file_uid", String(1024), nullable=False) + file_display_name = Column( + "file_display_name", UnicodeText().with_variant(UnicodeText(2048), "mysql"), nullable=True + ) + file_description = Column( + "file_description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True + ) + file_org_name = Column("file_org_name", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=False) # sha256 hash - file_hash = Column('file_hash', String(512), nullable=False) - file_size = Column('file_size', BigInteger(), nullable=False) + file_hash = Column("file_hash", String(512), nullable=False) + file_size = Column("file_size", BigInteger(), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True) - accessed_count = Column('accessed_count', Integer(), default=0) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True) + accessed_count = Column("accessed_count", Integer(), default=0) - enabled = Column('enabled', Boolean(), nullable=False, default=True) + enabled = Column("enabled", Boolean(), nullable=False, default=True) # if repo/repo_group reference is set, check for permissions - check_acl = Column('check_acl', Boolean(), nullable=False, default=True) + check_acl = Column("check_acl", Boolean(), nullable=False, default=True) # hidden defines an attachment that should be hidden from showing in artifact listing - hidden = Column('hidden', Boolean(), nullable=False, default=False) + hidden = Column("hidden", Boolean(), nullable=False, default=False) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - upload_user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.user_id') + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + upload_user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.user_id") - file_metadata = relationship('FileStoreMetadata', lazy='joined') + file_metadata = relationship("FileStoreMetadata", lazy="joined") # scope limited to user, which requester have access to scope_user_id = Column( - 'scope_user_id', Integer(), ForeignKey('users.user_id'), - nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined', primaryjoin='User.user_id==FileStore.scope_user_id') + "scope_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + user = relationship("User", lazy="joined", primaryjoin="User.user_id==FileStore.scope_user_id") # scope limited to user group, which requester have access to scope_user_group_id = Column( - 'scope_user_group_id', Integer(), ForeignKey('users_groups.users_group_id'), - nullable=True, unique=None, default=None) - user_group = relationship('UserGroup', lazy='joined') + "scope_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=True, + unique=None, + default=None, + ) + user_group = relationship("UserGroup", lazy="joined") # scope limited to repo, which requester have access to scope_repo_id = Column( - 'scope_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + "scope_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + repo = relationship("Repository", lazy="joined") # scope limited to repo group, which requester have access to scope_repo_group_id = Column( - 'scope_repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "scope_repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @classmethod def get_by_store_uid(cls, file_store_uid): return FileStore.query().filter(FileStore.file_uid == file_store_uid).scalar() @classmethod - def create(cls, file_uid, filename, file_hash, file_size, file_display_name='', - file_description='', enabled=True, hidden=False, check_acl=True, - user_id=None, scope_user_id=None, scope_repo_id=None, scope_repo_group_id=None): - + def create( + cls, + file_uid, + filename, + file_hash, + file_size, + file_display_name="", + file_description="", + enabled=True, + hidden=False, + check_acl=True, + user_id=None, + scope_user_id=None, + scope_repo_id=None, + scope_repo_group_id=None, + ): store_entry = FileStore() store_entry.file_uid = file_uid store_entry.file_display_name = file_display_name @@ -5473,14 +5440,16 @@ class FileStore(Base, BaseModel): return for section, key, value, value_type in args: - has_key = FileStoreMetadata().query() \ - .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) \ - .filter(FileStoreMetadata.file_store_meta_section == section) \ - .filter(FileStoreMetadata.file_store_meta_key == key) \ + has_key = ( + FileStoreMetadata() + .query() + .filter(FileStoreMetadata.file_store_id == file_store.file_store_id) + .filter(FileStoreMetadata.file_store_meta_section == section) + .filter(FileStoreMetadata.file_store_meta_key == key) .scalar() + ) if has_key: - msg = 'key `{}` already defined under section `{}` for this file.'\ - .format(key, section) + msg = "key `{}` already defined under section `{}` for this file.".format(key, section) raise ArtifactMetadataDuplicate(msg, err_section=section, err_key=key) # NOTE(marcink): raises ArtifactMetadataBadValueType @@ -5500,86 +5469,99 @@ class FileStore(Base, BaseModel): Session().commit() except IntegrityError: Session().rollback() - raise ArtifactMetadataDuplicate('Duplicate section/key found for this file.') + raise ArtifactMetadataDuplicate("Duplicate section/key found for this file.") @classmethod def bump_access_counter(cls, file_uid, commit=True): - FileStore().query()\ - .filter(FileStore.file_uid == file_uid)\ - .update({FileStore.accessed_count: (FileStore.accessed_count + 1), - FileStore.accessed_on: datetime.datetime.now()}) + FileStore().query().filter(FileStore.file_uid == file_uid).update( + {FileStore.accessed_count: (FileStore.accessed_count + 1), FileStore.accessed_on: datetime.datetime.now()} + ) if commit: Session().commit() def __json__(self): data = { - 'filename': self.file_display_name, - 'filename_org': self.file_org_name, - 'file_uid': self.file_uid, - 'description': self.file_description, - 'hidden': self.hidden, - 'size': self.file_size, - 'created_on': self.created_on, - 'uploaded_by': self.upload_user.get_api_data(details='basic'), - 'downloaded_times': self.accessed_count, - 'sha256': self.file_hash, - 'metadata': self.file_metadata, + "filename": self.file_display_name, + "filename_org": self.file_org_name, + "file_uid": self.file_uid, + "description": self.file_description, + "hidden": self.hidden, + "size": self.file_size, + "created_on": self.created_on, + "uploaded_by": self.upload_user.get_api_data(details="basic"), + "downloaded_times": self.accessed_count, + "sha256": self.file_hash, + "metadata": self.file_metadata, } return data def __repr__(self): - return ''.format(self.file_store_id) + return "".format(self.file_store_id) class FileStoreMetadata(Base, BaseModel): - __tablename__ = 'file_store_metadata' + __tablename__ = "file_store_metadata" __table_args__ = ( - UniqueConstraint('file_store_id', 'file_store_meta_section_hash', 'file_store_meta_key_hash'), - Index('file_store_meta_section_idx', 'file_store_meta_section', mysql_length=255), - Index('file_store_meta_key_idx', 'file_store_meta_key', mysql_length=255), - base_table_args + UniqueConstraint("file_store_id", "file_store_meta_section_hash", "file_store_meta_key_hash"), + Index("file_store_meta_section_idx", "file_store_meta_section", mysql_length=255), + Index("file_store_meta_key_idx", "file_store_meta_key", mysql_length=255), + base_table_args, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } file_store_meta_id = Column( - "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) + "file_store_meta_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) _file_store_meta_section = Column( - "file_store_meta_section", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_section", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_section_hash = Column( - "file_store_meta_section_hash", String(255), - nullable=True, unique=None, default=None) + "file_store_meta_section_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_key = Column( - "file_store_meta_key", UnicodeText().with_variant(UnicodeText(1024), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_key", + UnicodeText().with_variant(UnicodeText(1024), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_key_hash = Column( - "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None) + "file_store_meta_key_hash", String(255), nullable=True, unique=None, default=None + ) _file_store_meta_value = Column( - "file_store_meta_value", UnicodeText().with_variant(UnicodeText(20480), 'mysql'), - nullable=True, unique=None, default=None) + "file_store_meta_value", + UnicodeText().with_variant(UnicodeText(20480), "mysql"), + nullable=True, + unique=None, + default=None, + ) _file_store_meta_value_type = Column( - "file_store_meta_value_type", String(255), nullable=True, unique=None, - default='unicode') + "file_store_meta_value_type", String(255), nullable=True, unique=None, default="unicode" + ) file_store_id = Column( - 'file_store_id', Integer(), ForeignKey('file_store.file_store_id'), - nullable=True, unique=None, default=None) + "file_store_id", Integer(), ForeignKey("file_store.file_store_id"), nullable=True, unique=None, default=None + ) - file_store = relationship('FileStore', lazy='joined') + file_store = relationship("FileStore", lazy="joined") @classmethod def valid_value_type(cls, value): - if value.split('.')[0] not in cls.SETTINGS_TYPES: + if value.split(".")[0] not in cls.SETTINGS_TYPES: raise ArtifactMetadataBadValueType( - 'value_type must be one of %s got %s' % (cls.SETTINGS_TYPES.keys(), value)) + "value_type must be one of %s got %s" % (cls.SETTINGS_TYPES.keys(), value) + ) @hybrid_property def file_store_meta_section(self): @@ -5605,13 +5587,13 @@ class FileStoreMetadata(Base, BaseModel): if self._file_store_meta_value_type: # e.g unicode.encrypted == unicode - _type = self._file_store_meta_value_type.split('.')[0] + _type = self._file_store_meta_value_type.split(".")[0] # decode the encrypted value if it's encrypted field type - if '.encrypted' in self._file_store_meta_value_type: + if ".encrypted" in self._file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_result_value(val, None)) # do final type conversion - converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] val = converter(val) return val @@ -5620,7 +5602,7 @@ class FileStoreMetadata(Base, BaseModel): def file_store_meta_value(self, val): val = safe_str(val) # encode the encrypted value - if '.encrypted' in self.file_store_meta_value_type: + if ".encrypted" in self.file_store_meta_value_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._file_store_meta_value = val @@ -5637,28 +5619,30 @@ class FileStoreMetadata(Base, BaseModel): def __json__(self): data = { - 'artifact': self.file_store.file_uid, - 'section': self.file_store_meta_section, - 'key': self.file_store_meta_key, - 'value': self.file_store_meta_value, + "artifact": self.file_store.file_uid, + "section": self.file_store_meta_section, + "key": self.file_store_meta_key, + "value": self.file_store_meta_value, } return data def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.file_store_meta_section, - self.file_store_meta_key, self.file_store_meta_value) + return "<%s[%s]%s=>%s]>" % ( + self.__class__.__name__, + self.file_store_meta_section, + self.file_store_meta_key, + self.file_store_meta_value, + ) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_migrate_version" + __table_args__ = (base_table_args,) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) @classmethod def set_version(cls, version): @@ -5671,16 +5655,14 @@ class DbMigrateVersion(Base, BaseModel): class DbSession(Base, BaseModel): - __tablename__ = 'db_session' - __table_args__ = ( - base_table_args, - ) + __tablename__ = "db_session" + __table_args__ = (base_table_args,) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_3_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_3_0_0.py index a8109ab4..4c9e775f 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_3_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_3_0_0.py @@ -36,8 +36,7 @@ from sqlalchemy import * from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound @@ -50,18 +49,27 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -76,10 +84,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -91,8 +99,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -109,18 +117,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -128,27 +135,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -159,20 +165,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -183,11 +189,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -242,49 +253,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -294,14 +306,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -313,7 +324,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -324,93 +335,72 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -420,7 +410,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -440,63 +430,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -510,48 +496,54 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -568,7 +560,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query().filter(UserEmailMap.user==self).all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).all() return [self.email] + [x.email for x in other] @property @@ -581,10 +573,9 @@ class User(Base, BaseModel): @property def feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key else: @@ -593,12 +584,13 @@ class User(Base, BaseModel): @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() @property @@ -608,29 +600,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.firstname, self.lastname) - if (self.firstname and self.lastname) else self.username) + return "%s %s" % (self.firstname, self.lastname) if (self.firstname and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -642,8 +633,8 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser - return AuthUser(user_id=self.user_id, api_key=self.api_key, - username=self.username) + + return AuthUser(user_id=self.user_id, api_key=self.api_key, username=self.username) @hybrid_property def user_data(self): @@ -658,32 +649,28 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_user_by_name_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_by_name_%s" % _hash_key(username))) return q.scalar() @@ -692,24 +679,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -717,8 +703,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % email)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email)) ret = q.scalar() if ret is None: @@ -730,9 +715,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -744,6 +728,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -762,25 +747,25 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" usr = self old = usr.user_data - old.update({'last_activity': time.time()}) + old.update({"last_activity": time.time()}) usr.user_data = old Session().add(usr) - log.debug('updated user %s lastactivity', usr.username) + log.debug("updated user %s lastactivity", usr.username) def update_password(self, new_password, change_api_key=False): - from rhodecode.lib.auth import get_crypt_password,generate_auth_token + from rhodecode.lib.auth import get_crypt_password, generate_auth_token self.password = get_crypt_password(new_password) if change_api_key: @@ -791,7 +776,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -799,24 +784,24 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -830,85 +815,83 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data api_key_length = 40 - api_key_replacement = '*' * api_key_length + api_key_replacement = "*" * api_key_length extras = { - 'api_key': api_key_replacement, - 'api_keys': [api_key_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "api_key": api_key_replacement, + "api_keys": [api_key_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['api_key'] = user.api_key - data['api_keys'] = user.auth_tokens + data["api_key"] = user.api_key + data["api_keys"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -923,26 +906,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -955,20 +936,18 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_ip_range(cls, ip_addr): @@ -977,66 +956,68 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") @hybrid_property def group_data(self): @@ -1056,38 +1037,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1105,7 +1081,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1129,9 +1105,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1141,11 +1119,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1157,203 +1136,183 @@ class UserGroup(Base, BaseModel): user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, } if with_group_members: users = [] for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1362,13 +1321,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1414,13 +1374,11 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_repo_by_name_%s" % _hash_key(repo_name))) + q = q.options(FromCache("sql_cache_short", "get_repo_by_name_%s" % _hash_key(repo_name))) return q.scalar() @@ -1441,8 +1399,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1459,8 +1416,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1502,7 +1458,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1520,8 +1476,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1539,10 +1494,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1559,13 +1511,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1583,7 +1538,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1606,11 +1561,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1635,31 +1591,29 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': url('summary_home', repo_name=self.repo_name, qualified=True), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": url("summary_home", repo_name=self.repo_name, qualified=True), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1707,7 +1661,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1720,40 +1674,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1767,42 +1719,46 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(clone_uri) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): - qualified_home_url = '/' + qualified_home_url = "/" uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: uri_tmpl = self.DEFAULT_CLONE_URI - return get_clone_url(uri_tmpl=uri_tmpl, - qualifed_home_url=qualified_home_url, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + uri_tmpl=uri_tmpl, + qualifed_home_url=qualified_home_url, + repo_name=self.repo_name, + repo_id=self.repo_id, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -1812,8 +1768,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -1840,12 +1795,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -1853,28 +1808,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -1890,8 +1845,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -1905,19 +1859,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -1937,8 +1886,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -1950,9 +1898,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -1966,75 +1914,73 @@ class Repository(Base, BaseModel): repo_full_path = self.repo_full_path try: vcs_alias = get_scm(repo_full_path)[0] - log.debug( - 'Creating instance of %s repository from %s', - vcs_alias, repo_full_path) + log.debug("Creating instance of %s repository from %s", vcs_alias, repo_full_path) backend = get_backend(vcs_alias) except VCSError: log.exception( - 'Perhaps this repository is in db and not in ' - 'filesystem run rescan repositories with ' - '"destroy old data" option from admin panel') + "Perhaps this repository is in db and not in " + "filesystem run rescan repositories with " + '"destroy old data" option from admin panel' + ) return config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } - repo = backend( - safe_str(repo_full_path), config=config, create=False, - with_wire=custom_wire) + repo = backend(safe_str(repo_full_path), config=config, create=False, with_wire=custom_wire) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2045,12 +1991,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [('-1', u'-- %s --' % _('No parent'))] + repo_groups = [("-1", "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2060,19 +2005,15 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2098,14 +2039,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2129,9 +2073,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2180,15 +2122,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2206,7 +2149,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2230,9 +2173,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2249,110 +2194,100 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.group_description, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.group_description, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2360,9 +2295,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2370,130 +2303,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2505,24 +2417,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2534,42 +2451,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2581,25 +2511,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2611,40 +2557,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2657,21 +2619,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2683,45 +2655,53 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2729,31 +2709,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -2795,13 +2772,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -2812,19 +2789,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -2836,35 +2809,36 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -2875,8 +2849,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -2885,28 +2858,28 @@ class ChangesetComment(Base, BaseModel): def render(self, mentions=False): from rhodecode.lib import helpers as h + return h.render(self.text, renderer=self.renderer, mentions=mentions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -2915,26 +2888,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -2951,177 +2921,155 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) + target_ref = Column("other_ref", Unicode(255), nullable=False) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): - refs = self.source_ref.split(':') + refs = self.source_ref.split(":") return Reference(refs[0], refs[1], refs[2]) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): - refs = self.target_ref.split(':') + refs = self.target_ref.split(":") return Reference(refs[0], refs[1], refs[2]) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") def is_closed(self): return self.status == self.STATUS_CLOSED def get_api_data(self): from rhodecode.model.pull_request import PullRequestModel + pull_request = self merge_status = PullRequestModel().merge_status(pull_request) data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': url('pullrequest_show', repo_name=self.target_repo.repo_name, - pull_request_id=self.pull_request_id, - qualified=True), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': merge_status[0], - 'message': str(merge_status[1]), + "pull_request_id": pull_request.pull_request_id, + "url": url( + "pullrequest_show", + repo_name=self.target_repo.repo_name, + pull_request_id=self.pull_request_id, + qualified=True, + ), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": merge_status[0], + "message": str(merge_status[1]), }, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "review_status": st[0][1].status if st else "not_reviewed", } for reviewer, st in pull_request.reviewers_statuses() - ] + ], } return data def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): @@ -3129,90 +3077,84 @@ class PullRequest(Base, _PullRequestBase): # because it's tricky on how to use ChangesetStatusModel from there warnings.warn("Use calculated_review_status from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): warnings.warn("Use reviewers_statuses from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3243,24 +3185,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3268,34 +3215,33 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @classmethod def get_or_404(cls, id_): @@ -3310,11 +3256,12 @@ class Gist(Base, BaseModel): def gist_url(self): import rhodecode - alias_url = rhodecode.CONFIG.get('gist_alias_url') - if alias_url: - return alias_url.replace('{gistid}', self.gist_access_id) - return url('gist', gist_id=self.gist_access_id, qualified=True) + alias_url = rhodecode.CONFIG.get("gist_alias_url") + if alias_url: + return alias_url.replace("{gistid}", self.gist_access_id) + + return url("gist", gist_id=self.gist_access_id, qualified=True) @classmethod def base_path(cls): @@ -3324,8 +3271,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3335,66 +3282,61 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): from rhodecode.lib.vcs import get_repo + base_path = self.base_path() - return get_repo(os.path.join(*map(safe_str, - [base_path, self.gist_access_id]))) + return get_repo(os.path.join(*map(safe_str, [base_path, self.gist_access_id]))) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3438,26 +3380,25 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) enabled = Column("enabled", Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - settings_json = Column('settings_json', - UnicodeText().with_variant(UnicodeText(16384), 'mysql')) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + name = Column("name", String(255), nullable=False) + settings_json = Column("settings_json", UnicodeText().with_variant(UnicodeText(16384), "mysql")) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") @hybrid_property def settings(self): - data = json.loads(self.settings_json or '{}') + data = json.loads(self.settings_json or "{}") return data @settings.setter @@ -3466,11 +3407,11 @@ class Integration(Base, BaseModel): def __repr__(self): if self.repo: - scope = 'repo=%r' % self.repo + scope = "repo=%r" % self.repo else: - scope = 'global' + scope = "global" - return '' % (self.integration_type, scope) + return "" % (self.integration_type, scope) def settings_as_dict(self): return json.loads(self.settings_json) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_4_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_4_0_0.py index efab6bc2..f0a27ca7 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_4_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_4_0_0.py @@ -36,8 +36,7 @@ from sqlalchemy import * from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound @@ -50,11 +49,20 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend, get_vcs_instance from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.jsonalchemy import MutationObj, JsonType from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache @@ -62,7 +70,7 @@ from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -77,10 +85,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -92,8 +100,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -110,18 +118,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -129,27 +136,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -160,20 +166,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -184,11 +190,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -243,49 +254,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -295,14 +307,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -314,7 +325,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -325,93 +336,72 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -421,7 +411,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -441,63 +431,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -511,48 +497,54 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -569,7 +561,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query().filter(UserEmailMap.user==self).all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).all() return [self.email] + [x.email for x in other] @property @@ -582,10 +574,9 @@ class User(Base, BaseModel): @property def feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key else: @@ -594,12 +585,13 @@ class User(Base, BaseModel): @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() @property @@ -609,29 +601,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.firstname, self.lastname) - if (self.firstname and self.lastname) else self.username) + return "%s %s" % (self.firstname, self.lastname) if (self.firstname and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -643,8 +634,8 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser - return AuthUser(user_id=self.user_id, api_key=self.api_key, - username=self.username) + + return AuthUser(user_id=self.user_id, api_key=self.api_key, username=self.username) @hybrid_property def user_data(self): @@ -659,32 +650,28 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_user_by_name_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_by_name_%s" % _hash_key(username))) return q.scalar() @@ -693,24 +680,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -718,8 +704,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % _hash_key(email))) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % _hash_key(email))) ret = q.scalar() if ret is None: @@ -731,9 +716,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -745,6 +729,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -763,25 +748,25 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" usr = self old = usr.user_data - old.update({'last_activity': time.time()}) + old.update({"last_activity": time.time()}) usr.user_data = old Session().add(usr) - log.debug('updated user %s lastactivity', usr.username) + log.debug("updated user %s lastactivity", usr.username) def update_password(self, new_password, change_api_key=False): - from rhodecode.lib.auth import get_crypt_password,generate_auth_token + from rhodecode.lib.auth import get_crypt_password, generate_auth_token self.password = get_crypt_password(new_password) if change_api_key: @@ -792,7 +777,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -800,24 +785,24 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -831,85 +816,83 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data api_key_length = 40 - api_key_replacement = '*' * api_key_length + api_key_replacement = "*" * api_key_length extras = { - 'api_key': api_key_replacement, - 'api_keys': [api_key_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "api_key": api_key_replacement, + "api_keys": [api_key_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['api_key'] = user.api_key - data['api_keys'] = user.auth_tokens + data["api_key"] = user.api_key + data["api_keys"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -924,26 +907,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -956,20 +937,18 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_ip_range(cls, ip_addr): @@ -978,66 +957,68 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") @hybrid_property def group_data(self): @@ -1057,38 +1038,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1106,7 +1082,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1130,9 +1106,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1142,11 +1120,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1158,205 +1137,184 @@ class UserGroup(Base, BaseModel): user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, } if with_group_members: users = [] for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1365,13 +1323,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1417,13 +1376,11 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_repo_by_name_%s" % _hash_key(repo_name))) + q = q.options(FromCache("sql_cache_short", "get_repo_by_name_%s" % _hash_key(repo_name))) return q.scalar() @@ -1444,8 +1401,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1462,8 +1418,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1505,7 +1460,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1523,8 +1478,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1542,10 +1496,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1562,13 +1513,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1586,7 +1540,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1609,11 +1563,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1638,31 +1593,29 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': url('summary_home', repo_name=self.repo_name, qualified=True), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": url("summary_home", repo_name=self.repo_name, qualified=True), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1710,7 +1663,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1723,40 +1676,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1770,42 +1721,46 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(clone_uri) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): - qualified_home_url = '/' + qualified_home_url = "/" uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: uri_tmpl = self.DEFAULT_CLONE_URI - return get_clone_url(uri_tmpl=uri_tmpl, - qualifed_home_url=qualified_home_url, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + uri_tmpl=uri_tmpl, + qualifed_home_url=qualified_home_url, + repo_name=self.repo_name, + repo_id=self.repo_id, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -1815,8 +1770,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -1843,12 +1797,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -1856,28 +1810,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -1893,8 +1847,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -1908,19 +1861,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -1940,8 +1888,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -1953,9 +1900,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -1968,65 +1915,64 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( - repo_path=safe_str(self.repo_full_path), - config=config, - with_wire=custom_wire, - create=False) + repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2037,12 +1983,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [('-1', u'-- %s --' % _('No parent'))] + repo_groups = [("-1", "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2052,19 +1997,15 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2090,14 +2031,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2121,9 +2065,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2172,15 +2114,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2198,7 +2141,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2222,9 +2165,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2241,110 +2186,100 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.group_description, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.group_description, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2352,9 +2287,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2362,130 +2295,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2497,24 +2409,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2526,42 +2443,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2573,25 +2503,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2603,40 +2549,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2649,21 +2611,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2675,45 +2647,53 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2721,31 +2701,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -2787,13 +2764,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -2804,19 +2781,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -2828,35 +2801,36 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -2867,8 +2841,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -2877,28 +2850,28 @@ class ChangesetComment(Base, BaseModel): def render(self, mentions=False): from rhodecode.lib import helpers as h + return h.render(self.text, renderer=self.renderer, mentions=mentions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -2907,26 +2880,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -2943,177 +2913,155 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) + target_ref = Column("other_ref", Unicode(255), nullable=False) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): - refs = self.source_ref.split(':') + refs = self.source_ref.split(":") return Reference(refs[0], refs[1], refs[2]) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): - refs = self.target_ref.split(':') + refs = self.target_ref.split(":") return Reference(refs[0], refs[1], refs[2]) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") def is_closed(self): return self.status == self.STATUS_CLOSED def get_api_data(self): from rhodecode.model.pull_request import PullRequestModel + pull_request = self merge_status = PullRequestModel().merge_status(pull_request) data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': url('pullrequest_show', repo_name=self.target_repo.repo_name, - pull_request_id=self.pull_request_id, - qualified=True), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': merge_status[0], - 'message': str(merge_status[1]), + "pull_request_id": pull_request.pull_request_id, + "url": url( + "pullrequest_show", + repo_name=self.target_repo.repo_name, + pull_request_id=self.pull_request_id, + qualified=True, + ), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": merge_status[0], + "message": str(merge_status[1]), }, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "review_status": st[0][1].status if st else "not_reviewed", } for reviewer, st in pull_request.reviewers_statuses() - ] + ], } return data def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): @@ -3121,90 +3069,84 @@ class PullRequest(Base, _PullRequestBase): # because it's tricky on how to use ChangesetStatusModel from there warnings.warn("Use calculated_review_status from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): warnings.warn("Use reviewers_statuses from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3235,24 +3177,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3260,34 +3207,33 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @classmethod def get_or_404(cls, id_): @@ -3302,11 +3248,12 @@ class Gist(Base, BaseModel): def gist_url(self): import rhodecode - alias_url = rhodecode.CONFIG.get('gist_alias_url') - if alias_url: - return alias_url.replace('{gistid}', self.gist_access_id) - return url('gist', gist_id=self.gist_access_id, qualified=True) + alias_url = rhodecode.CONFIG.get("gist_alias_url") + if alias_url: + return alias_url.replace("{gistid}", self.gist_access_id) + + return url("gist", gist_id=self.gist_access_id, qualified=True) @classmethod def base_path(cls): @@ -3316,8 +3263,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3327,65 +3274,59 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3429,35 +3370,33 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") def __repr__(self): if self.repo: - scope = 'repo=%r' % self.repo + scope = "repo=%r" % self.repo elif self.repo_group: - scope = 'repo_group=%r' % self.repo_group + scope = "repo_group=%r" % self.repo_group else: - scope = 'global' + scope = "global" - return '' % (self.integration_type, scope) + return "" % (self.integration_type, scope) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_4_0_1.py b/rhodecode/lib/dbmigrate/schema/db_4_4_0_1.py index f17255c2..21aaf4b7 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_4_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_4_0_1.py @@ -36,12 +36,12 @@ from sqlalchemy import * from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound from zope.cachedescriptors.property import Lazy as LazyProperty + # replace pylons with fake url for migration from rhodecode.lib.dbmigrate.schema import url from rhodecode.translation import _ @@ -49,11 +49,20 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend, get_vcs_instance from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, +) from rhodecode.lib.jsonalchemy import MutationObj, JsonType from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache @@ -61,7 +70,7 @@ from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -76,10 +85,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -91,8 +100,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -109,18 +118,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -128,27 +136,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -159,20 +166,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -183,11 +190,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -242,49 +254,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -294,14 +307,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -313,7 +325,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -324,93 +336,72 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -420,7 +411,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -440,63 +431,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -510,48 +497,54 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -568,7 +561,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query().filter(UserEmailMap.user==self).all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).all() return [self.email] + [x.email for x in other] @property @@ -581,10 +574,9 @@ class User(Base, BaseModel): @property def feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key else: @@ -593,12 +585,13 @@ class User(Base, BaseModel): @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() @property @@ -608,29 +601,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.firstname, self.lastname) - if (self.firstname and self.lastname) else self.username) + return "%s %s" % (self.firstname, self.lastname) if (self.firstname and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -642,8 +634,8 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser - return AuthUser(user_id=self.user_id, api_key=self.api_key, - username=self.username) + + return AuthUser(user_id=self.user_id, api_key=self.api_key, username=self.username) @hybrid_property def user_data(self): @@ -658,32 +650,28 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_user_by_name_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_by_name_%s" % _hash_key(username))) return q.scalar() @@ -692,24 +680,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -717,8 +704,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % _hash_key(email))) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % _hash_key(email))) ret = q.scalar() if ret is None: @@ -730,9 +716,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -744,6 +729,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -762,25 +748,25 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" usr = self old = usr.user_data - old.update({'last_activity': time.time()}) + old.update({"last_activity": time.time()}) usr.user_data = old Session().add(usr) - log.debug('updated user %s lastactivity', usr.username) + log.debug("updated user %s lastactivity", usr.username) def update_password(self, new_password, change_api_key=False): - from rhodecode.lib.auth import get_crypt_password,generate_auth_token + from rhodecode.lib.auth import get_crypt_password, generate_auth_token self.password = get_crypt_password(new_password) if change_api_key: @@ -791,7 +777,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -799,24 +785,24 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -830,85 +816,83 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data api_key_length = 40 - api_key_replacement = '*' * api_key_length + api_key_replacement = "*" * api_key_length extras = { - 'api_key': api_key_replacement, - 'api_keys': [api_key_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "api_key": api_key_replacement, + "api_keys": [api_key_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['api_key'] = user.api_key - data['api_keys'] = user.auth_tokens + data["api_key"] = user.api_key + data["api_keys"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -923,26 +907,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -955,20 +937,18 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_ip_range(cls, ip_addr): @@ -977,66 +957,68 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") @hybrid_property def group_data(self): @@ -1056,38 +1038,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1105,7 +1082,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1129,9 +1106,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1141,11 +1120,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1157,205 +1137,184 @@ class UserGroup(Base, BaseModel): user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, } if with_group_members: users = [] for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1364,13 +1323,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1416,13 +1376,11 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_repo_by_name_%s" % _hash_key(repo_name))) + q = q.options(FromCache("sql_cache_short", "get_repo_by_name_%s" % _hash_key(repo_name))) return q.scalar() @@ -1443,8 +1401,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1461,8 +1418,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1504,7 +1460,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1522,8 +1478,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1541,10 +1496,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1561,13 +1513,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1585,7 +1540,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1608,11 +1563,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1637,31 +1593,29 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': url('summary_home', repo_name=self.repo_name, qualified=True), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": url("summary_home", repo_name=self.repo_name, qualified=True), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1709,7 +1663,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1722,40 +1676,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1769,42 +1721,46 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(clone_uri) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): - qualified_home_url = '/' + qualified_home_url = "/" uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: uri_tmpl = self.DEFAULT_CLONE_URI - return get_clone_url(uri_tmpl=uri_tmpl, - qualifed_home_url=qualified_home_url, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + uri_tmpl=uri_tmpl, + qualifed_home_url=qualified_home_url, + repo_name=self.repo_name, + repo_id=self.repo_id, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -1814,8 +1770,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -1842,12 +1797,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -1855,28 +1810,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -1892,8 +1847,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -1907,19 +1861,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -1939,8 +1888,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -1952,9 +1900,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -1967,65 +1915,64 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( - repo_path=safe_str(self.repo_full_path), - config=config, - with_wire=custom_wire, - create=False) + repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2036,12 +1983,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [('-1', u'-- %s --' % _('No parent'))] + repo_groups = [("-1", "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2051,19 +1997,15 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2089,14 +2031,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2120,9 +2065,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2171,15 +2114,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2197,7 +2141,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2221,9 +2165,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2240,110 +2186,100 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.group_description, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.group_description, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2351,9 +2287,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2361,130 +2295,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2496,24 +2409,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2525,42 +2443,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2572,25 +2503,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2602,40 +2549,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2648,21 +2611,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2674,45 +2647,53 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2720,31 +2701,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -2786,13 +2764,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -2803,19 +2781,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -2826,37 +2800,37 @@ class CacheKey(Base, BaseModel): return None - class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -2867,8 +2841,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -2877,28 +2850,28 @@ class ChangesetComment(Base, BaseModel): def render(self, mentions=False): from rhodecode.lib import helpers as h + return h.render(self.text, renderer=self.renderer, mentions=mentions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -2907,26 +2880,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -2943,177 +2913,155 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) + target_ref = Column("other_ref", Unicode(255), nullable=False) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): - refs = self.source_ref.split(':') + refs = self.source_ref.split(":") return Reference(refs[0], refs[1], refs[2]) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): - refs = self.target_ref.split(':') + refs = self.target_ref.split(":") return Reference(refs[0], refs[1], refs[2]) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") def is_closed(self): return self.status == self.STATUS_CLOSED def get_api_data(self): from rhodecode.model.pull_request import PullRequestModel + pull_request = self merge_status = PullRequestModel().merge_status(pull_request) data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': url('pullrequest_show', repo_name=self.target_repo.repo_name, - pull_request_id=self.pull_request_id, - qualified=True), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': merge_status[0], - 'message': str(merge_status[1]), + "pull_request_id": pull_request.pull_request_id, + "url": url( + "pullrequest_show", + repo_name=self.target_repo.repo_name, + pull_request_id=self.pull_request_id, + qualified=True, + ), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": merge_status[0], + "message": str(merge_status[1]), }, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "review_status": st[0][1].status if st else "not_reviewed", } for reviewer, st in pull_request.reviewers_statuses() - ] + ], } return data def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): @@ -3121,90 +3069,84 @@ class PullRequest(Base, _PullRequestBase): # because it's tricky on how to use ChangesetStatusModel from there warnings.warn("Use calculated_review_status from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): warnings.warn("Use reviewers_statuses from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3235,24 +3177,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3260,34 +3207,33 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @classmethod def get_or_404(cls, id_): @@ -3302,11 +3248,12 @@ class Gist(Base, BaseModel): def gist_url(self): import rhodecode - alias_url = rhodecode.CONFIG.get('gist_alias_url') - if alias_url: - return alias_url.replace('{gistid}', self.gist_access_id) - return url('gist', gist_id=self.gist_access_id, qualified=True) + alias_url = rhodecode.CONFIG.get("gist_alias_url") + if alias_url: + return alias_url.replace("{gistid}", self.gist_access_id) + + return url("gist", gist_id=self.gist_access_id, qualified=True) @classmethod def base_path(cls): @@ -3316,8 +3263,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3327,65 +3274,59 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3429,30 +3370,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=True) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=True) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @hybrid_property def scope(self): @@ -3461,8 +3400,8 @@ class Integration(Base, BaseModel): if self.repo_group: return self.repo_group if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" @scope.setter def scope(self, value): @@ -3475,13 +3414,14 @@ class Integration(Base, BaseModel): self.repo = value elif isinstance(value, RepoGroup): self.repo_group = value - elif value == 'root_repos': + elif value == "root_repos": self.child_repos_only = True - elif value == 'global': + elif value == "global": pass else: - raise Exception("invalid scope: %s, must be one of " - "['global', 'root_repos', . ]" % value) + raise Exception( + "invalid scope: %s, must be one of ['global', 'root_repos', . ]" % value + ) def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_4_0_2.py b/rhodecode/lib/dbmigrate/schema/db_4_4_0_2.py index 50787654..926a3584 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_4_0_2.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_4_0_2.py @@ -37,12 +37,12 @@ from sqlalchemy import * from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound from zope.cachedescriptors.property import Lazy as LazyProperty + # replace pylons with fake url for migration from rhodecode.lib.dbmigrate.schema import url from rhodecode.translation import _ @@ -50,12 +50,21 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend, get_vcs_instance from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, +) from rhodecode.lib.jsonalchemy import MutationObj, JsonType from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache @@ -63,7 +72,7 @@ from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -78,10 +87,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -93,8 +102,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -111,18 +120,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -130,27 +138,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -161,20 +168,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -185,11 +192,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -244,49 +256,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -296,14 +309,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -315,7 +327,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -326,93 +338,72 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -422,7 +413,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -442,63 +433,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -512,48 +499,54 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -570,7 +563,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query().filter(UserEmailMap.user==self).all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).all() return [self.email] + [x.email for x in other] @property @@ -583,10 +576,9 @@ class User(Base, BaseModel): @property def feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key else: @@ -595,12 +587,13 @@ class User(Base, BaseModel): @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() @property @@ -610,29 +603,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.firstname, self.lastname) - if (self.firstname and self.lastname) else self.username) + return "%s %s" % (self.firstname, self.lastname) if (self.firstname and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -644,8 +636,8 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser - return AuthUser(user_id=self.user_id, api_key=self.api_key, - username=self.username) + + return AuthUser(user_id=self.user_id, api_key=self.api_key, username=self.username) @hybrid_property def user_data(self): @@ -660,32 +652,28 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_user_by_name_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_by_name_%s" % _hash_key(username))) return q.scalar() @@ -694,24 +682,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -719,8 +706,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % _hash_key(email))) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % _hash_key(email))) ret = q.scalar() if ret is None: @@ -732,9 +718,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -746,6 +731,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -764,25 +750,25 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" usr = self old = usr.user_data - old.update({'last_activity': time.time()}) + old.update({"last_activity": time.time()}) usr.user_data = old Session().add(usr) - log.debug('updated user %s lastactivity', usr.username) + log.debug("updated user %s lastactivity", usr.username) def update_password(self, new_password, change_api_key=False): - from rhodecode.lib.auth import get_crypt_password,generate_auth_token + from rhodecode.lib.auth import get_crypt_password, generate_auth_token self.password = get_crypt_password(new_password) if change_api_key: @@ -793,7 +779,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -801,24 +787,24 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -832,85 +818,83 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data api_key_length = 40 - api_key_replacement = '*' * api_key_length + api_key_replacement = "*" * api_key_length extras = { - 'api_key': api_key_replacement, - 'api_keys': [api_key_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "api_key": api_key_replacement, + "api_keys": [api_key_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['api_key'] = user.api_key - data['api_keys'] = user.auth_tokens + data["api_key"] = user.api_key + data["api_keys"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -925,26 +909,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -957,20 +939,18 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_ip_range(cls, ip_addr): @@ -979,66 +959,68 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") @hybrid_property def group_data(self): @@ -1058,38 +1040,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1107,7 +1084,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1131,9 +1108,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1143,11 +1122,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1159,205 +1139,184 @@ class UserGroup(Base, BaseModel): user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, } if with_group_members: users = [] for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1366,13 +1325,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1418,13 +1378,11 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_repo_by_name_%s" % _hash_key(repo_name))) + q = q.options(FromCache("sql_cache_short", "get_repo_by_name_%s" % _hash_key(repo_name))) return q.scalar() @@ -1445,8 +1403,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1463,8 +1420,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1506,7 +1462,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1524,8 +1480,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1543,10 +1498,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1563,13 +1515,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1587,7 +1542,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1610,11 +1565,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1639,31 +1595,29 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': url('summary_home', repo_name=self.repo_name, qualified=True), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": url("summary_home", repo_name=self.repo_name, qualified=True), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1711,7 +1665,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1724,40 +1678,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1771,42 +1723,46 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(clone_uri) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): - qualified_home_url = '/' + qualified_home_url = "/" uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: uri_tmpl = self.DEFAULT_CLONE_URI - return get_clone_url(uri_tmpl=uri_tmpl, - qualifed_home_url=qualified_home_url, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + uri_tmpl=uri_tmpl, + qualifed_home_url=qualified_home_url, + repo_name=self.repo_name, + repo_id=self.repo_id, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -1816,8 +1772,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -1844,12 +1799,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -1857,28 +1812,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -1894,8 +1849,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -1909,19 +1863,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -1941,8 +1890,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -1954,9 +1902,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -1969,67 +1917,65 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( - repo_path=safe_str(self.repo_full_path), - config=config, - with_wire=custom_wire, - create=False) + repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2040,12 +1986,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [('-1', u'-- %s --' % _('No parent'))] + repo_groups = [("-1", "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2055,19 +2000,15 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2093,14 +2034,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2124,9 +2068,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2175,15 +2117,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2201,7 +2144,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2225,9 +2168,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2244,110 +2189,100 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.group_description, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.group_description, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2355,9 +2290,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2365,130 +2298,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2500,24 +2412,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2529,42 +2446,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2576,25 +2506,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2606,40 +2552,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2652,21 +2614,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2678,45 +2650,53 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2724,31 +2704,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -2790,13 +2767,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -2807,19 +2784,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -2831,35 +2804,36 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -2870,8 +2844,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -2880,28 +2853,28 @@ class ChangesetComment(Base, BaseModel): def render(self, mentions=False): from rhodecode.lib import helpers as h + return h.render(self.text, renderer=self.renderer, mentions=mentions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -2910,26 +2883,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -2946,177 +2916,155 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) + target_ref = Column("other_ref", Unicode(255), nullable=False) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): - refs = self.source_ref.split(':') + refs = self.source_ref.split(":") return Reference(refs[0], refs[1], refs[2]) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): - refs = self.target_ref.split(':') + refs = self.target_ref.split(":") return Reference(refs[0], refs[1], refs[2]) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") def is_closed(self): return self.status == self.STATUS_CLOSED def get_api_data(self): from rhodecode.model.pull_request import PullRequestModel + pull_request = self merge_status = PullRequestModel().merge_status(pull_request) data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': url('pullrequest_show', repo_name=self.target_repo.repo_name, - pull_request_id=self.pull_request_id, - qualified=True), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': merge_status[0], - 'message': str(merge_status[1]), + "pull_request_id": pull_request.pull_request_id, + "url": url( + "pullrequest_show", + repo_name=self.target_repo.repo_name, + pull_request_id=self.pull_request_id, + qualified=True, + ), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": merge_status[0], + "message": str(merge_status[1]), }, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "review_status": st[0][1].status if st else "not_reviewed", } for reviewer, st in pull_request.reviewers_statuses() - ] + ], } return data def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): @@ -3124,90 +3072,84 @@ class PullRequest(Base, _PullRequestBase): # because it's tricky on how to use ChangesetStatusModel from there warnings.warn("Use calculated_review_status from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): warnings.warn("Use reviewers_statuses from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None): self.user = user self.pull_request = pull_request - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3238,24 +3180,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3263,34 +3210,33 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @classmethod def get_or_404(cls, id_): @@ -3305,11 +3251,12 @@ class Gist(Base, BaseModel): def gist_url(self): import rhodecode - alias_url = rhodecode.CONFIG.get('gist_alias_url') - if alias_url: - return alias_url.replace('{gistid}', self.gist_access_id) - return url('gist', gist_id=self.gist_access_id, qualified=True) + alias_url = rhodecode.CONFIG.get("gist_alias_url") + if alias_url: + return alias_url.replace("{gistid}", self.gist_access_id) + + return url("gist", gist_id=self.gist_access_id, qualified=True) @classmethod def base_path(cls): @@ -3319,8 +3266,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3330,65 +3277,59 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3432,31 +3373,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -3464,90 +3402,87 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_user_id = Column( - 'repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), - nullable=False) - user = relationship('User') + __tablename__ = "repo_review_rules_users" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + user = relationship("User") class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_users_group_id = Column( - 'repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(), - ForeignKey('users_groups.users_group_id'), nullable=False) - users_group = relationship('UserGroup') + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) + users_group = relationship("UserGroup") class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob - use_authors_for_review = Column("use_authors_for_review", Boolean(), - nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" def _validate_pattern(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_glob(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, branch, files_changed): """ @@ -3557,16 +3492,16 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - branch = branch or '' + branch = branch or "" files_changed = files_changed or [] branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False file_regex = re.compile(glob2re(self.file_pattern)) for filename in files_changed: @@ -3578,12 +3513,10 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = set() - users |= set([ - rule_user.user for rule_user in self.rule_users - if rule_user.user.active]) + users |= set([rule_user.user for rule_user in self.rule_users if rule_user.user.active]) users |= set( member.user for rule_user_group in self.rule_user_groups @@ -3593,5 +3526,4 @@ class RepoReviewRule(Base, BaseModel): return users def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_5_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_5_0_0.py index 6bc089b9..67e33d65 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_5_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_5_0_0.py @@ -37,12 +37,12 @@ from sqlalchemy import * from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region, region_invalidate from webob.exc import HTTPNotFound from zope.cachedescriptors.property import Lazy as LazyProperty + # replace pylons with fake url for migration from rhodecode.lib.dbmigrate.schema import url from rhodecode.translation import _ @@ -50,12 +50,21 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_backend, get_vcs_instance from rhodecode.lib.vcs.utils.helpers import get_scm from rhodecode.lib.vcs.exceptions import VCSError -from rhodecode.lib.vcs.backends.base import ( - EmptyCommit, Reference, MergeFailureReason) +from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference, MergeFailureReason from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, remove_prefix, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re) + str2bool, + safe_str, + get_commit_safe, + remove_prefix, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, +) from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache @@ -63,7 +72,7 @@ from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -78,10 +87,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -93,8 +102,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -111,18 +120,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -130,27 +138,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -161,20 +168,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -185,11 +192,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -244,49 +256,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -296,14 +309,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -315,7 +327,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -326,93 +338,72 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -422,7 +413,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -442,63 +433,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -512,48 +499,54 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -570,7 +563,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query().filter(UserEmailMap.user==self).all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).all() return [self.email] + [x.email for x in other] @property @@ -583,10 +576,9 @@ class User(Base, BaseModel): @property def feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key else: @@ -595,12 +587,13 @@ class User(Base, BaseModel): @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() @property @@ -610,29 +603,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.firstname, self.lastname) - if (self.firstname and self.lastname) else self.username) + return "%s %s" % (self.firstname, self.lastname) if (self.firstname and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -644,8 +636,8 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser - return AuthUser(user_id=self.user_id, api_key=self.api_key, - username=self.username) + + return AuthUser(user_id=self.user_id, api_key=self.api_key, username=self.username) @hybrid_property def user_data(self): @@ -660,32 +652,28 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_user_by_name_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_by_name_%s" % _hash_key(username))) return q.scalar() @@ -694,24 +682,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -719,8 +706,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % _hash_key(email))) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % _hash_key(email))) ret = q.scalar() if ret is None: @@ -732,9 +718,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -746,6 +731,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -764,25 +750,25 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" usr = self old = usr.user_data - old.update({'last_activity': time.time()}) + old.update({"last_activity": time.time()}) usr.user_data = old Session().add(usr) - log.debug('updated user %s lastactivity', usr.username) + log.debug("updated user %s lastactivity", usr.username) def update_password(self, new_password, change_api_key=False): - from rhodecode.lib.auth import get_crypt_password,generate_auth_token + from rhodecode.lib.auth import get_crypt_password, generate_auth_token self.password = get_crypt_password(new_password) if change_api_key: @@ -793,7 +779,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -801,24 +787,24 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -832,85 +818,83 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data api_key_length = 40 - api_key_replacement = '*' * api_key_length + api_key_replacement = "*" * api_key_length extras = { - 'api_key': api_key_replacement, - 'api_keys': [api_key_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "api_key": api_key_replacement, + "api_keys": [api_key_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['api_key'] = user.api_key - data['api_keys'] = user.auth_tokens + data["api_key"] = user.api_key + data["api_keys"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -925,26 +909,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -957,20 +939,18 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_ip_range(cls, ip_addr): @@ -979,66 +959,68 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") @hybrid_property def group_data(self): @@ -1058,38 +1040,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1107,7 +1084,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1131,9 +1108,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1143,11 +1122,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1159,205 +1139,184 @@ class UserGroup(Base, BaseModel): user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, } if with_group_members: users = [] for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1366,13 +1325,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1418,13 +1378,11 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_repo_by_name_%s" % _hash_key(repo_name))) + q = q.options(FromCache("sql_cache_short", "get_repo_by_name_%s" % _hash_key(repo_name))) return q.scalar() @@ -1445,8 +1403,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1463,8 +1420,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1506,7 +1462,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1524,8 +1480,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1543,10 +1498,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1563,13 +1515,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1587,7 +1542,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1610,11 +1565,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1639,31 +1595,29 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': url('summary_home', repo_name=self.repo_name, qualified=True), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": url("summary_home", repo_name=self.repo_name, qualified=True), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1711,7 +1665,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1724,40 +1678,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1771,42 +1723,46 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(clone_uri) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): - qualified_home_url = '/' + qualified_home_url = "/" uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: uri_tmpl = self.DEFAULT_CLONE_URI - return get_clone_url(uri_tmpl=uri_tmpl, - qualifed_home_url=qualified_home_url, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + uri_tmpl=uri_tmpl, + qualifed_home_url=qualified_home_url, + repo_name=self.repo_name, + repo_id=self.repo_id, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -1816,8 +1772,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -1844,12 +1799,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -1857,28 +1812,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -1894,8 +1849,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -1909,19 +1863,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -1941,8 +1890,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -1954,9 +1902,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -1969,67 +1917,65 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( - repo_path=safe_str(self.repo_full_path), - config=config, - with_wire=custom_wire, - create=False) + repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2040,12 +1986,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [('-1', u'-- %s --' % _('No parent'))] + repo_groups = [("-1", "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2055,19 +2000,15 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2093,14 +2034,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2124,9 +2068,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2175,15 +2117,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2201,7 +2144,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2225,9 +2168,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2244,110 +2189,100 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.group_description, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.group_description, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2355,9 +2290,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2365,130 +2298,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2500,24 +2412,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2529,42 +2446,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2576,25 +2506,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2606,40 +2552,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2652,21 +2614,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2678,45 +2650,53 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2724,31 +2704,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -2790,13 +2767,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -2807,19 +2784,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -2831,35 +2804,36 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' + COMMENT_OUTDATED = "comment_outdated" - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan") - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -2870,8 +2844,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -2880,28 +2853,28 @@ class ChangesetComment(Base, BaseModel): def render(self, mentions=False): from rhodecode.lib import helpers as h + return h.render(self.text, renderer=self.renderer, mentions=mentions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -2910,26 +2883,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -2946,178 +2916,156 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) + target_ref = Column("other_ref", Unicode(255), nullable=False) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): - refs = self.source_ref.split(':') + refs = self.source_ref.split(":") return Reference(refs[0], refs[1], refs[2]) @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): - refs = self.target_ref.split(':') + refs = self.target_ref.split(":") return Reference(refs[0], refs[1], refs[2]) class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan") + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan") def is_closed(self): return self.status == self.STATUS_CLOSED def get_api_data(self): from rhodecode.model.pull_request import PullRequestModel + pull_request = self merge_status = PullRequestModel().merge_status(pull_request) data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': url('pullrequest_show', repo_name=self.target_repo.repo_name, - pull_request_id=self.pull_request_id, - qualified=True), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': merge_status[0], - 'message': str(merge_status[1]), + "pull_request_id": pull_request.pull_request_id, + "url": url( + "pullrequest_show", + repo_name=self.target_repo.repo_name, + pull_request_id=self.pull_request_id, + qualified=True, + ), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": merge_status[0], + "message": str(merge_status[1]), }, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } for reviewer, reasons, st in pull_request.reviewers_statuses() - ] + ], } return data def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): @@ -3125,40 +3073,37 @@ class PullRequest(Base, _PullRequestBase): # because it's tricky on how to use ChangesetStatusModel from there warnings.warn("Use calculated_review_status from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): warnings.warn("Use reviewers_statuses from ChangesetStatusModel", DeprecationWarning) from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None, reasons=None): @@ -3176,56 +3121,51 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3256,24 +3196,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3281,34 +3226,33 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @classmethod def get_or_404(cls, id_): @@ -3323,11 +3267,12 @@ class Gist(Base, BaseModel): def gist_url(self): import rhodecode - alias_url = rhodecode.CONFIG.get('gist_alias_url') - if alias_url: - return alias_url.replace('{gistid}', self.gist_access_id) - return url('gist', gist_id=self.gist_access_id, qualified=True) + alias_url = rhodecode.CONFIG.get("gist_alias_url") + if alias_url: + return alias_url.replace("{gistid}", self.gist_access_id) + + return url("gist", gist_id=self.gist_access_id, qualified=True) @classmethod def base_path(cls): @@ -3337,8 +3282,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3348,65 +3293,59 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3450,31 +3389,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -3482,90 +3418,87 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_user_id = Column( - 'repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), - nullable=False) - user = relationship('User') + __tablename__ = "repo_review_rules_users" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + user = relationship("User") class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_users_group_id = Column( - 'repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(), - ForeignKey('users_groups.users_group_id'), nullable=False) - users_group = relationship('UserGroup') + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) + users_group = relationship("UserGroup") class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob - use_authors_for_review = Column("use_authors_for_review", Boolean(), - nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_glob(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, branch, files_changed): """ @@ -3575,16 +3508,16 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - branch = branch or '' + branch = branch or "" files_changed = files_changed or [] branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False file_regex = re.compile(glob2re(self.file_pattern)) for filename in files_changed: @@ -3596,12 +3529,10 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = set() - users |= set([ - rule_user.user for rule_user in self.rule_users - if rule_user.user.active]) + users |= set([rule_user.user for rule_user in self.rule_users if rule_user.user.active]) users |= set( member.user for rule_user_group in self.rule_user_groups @@ -3611,5 +3542,4 @@ class RepoReviewRule(Base, BaseModel): return users def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_7_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_7_0_0.py index b0f658c4..7bb50ae0 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_7_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_7_0_0.py @@ -35,8 +35,7 @@ import collections from sqlalchemy import * from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region from webob.exc import HTTPNotFound @@ -49,9 +48,20 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) + str2bool, + safe_str, + get_commit_safe, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache @@ -59,7 +69,7 @@ from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -74,10 +84,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -89,8 +99,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -107,18 +117,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -126,27 +135,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -157,20 +165,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -181,11 +189,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -240,49 +253,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -292,14 +306,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -311,7 +324,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -322,94 +335,73 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -419,7 +411,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -439,63 +431,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -509,48 +497,54 @@ class User(Base, BaseModel): extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -567,7 +561,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query().filter(UserEmailMap.user==self).all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).all() return [self.email] + [x.email for x in other] @property @@ -583,30 +577,28 @@ class User(Base, BaseModel): return self.get_feed_token() def get_feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() - def authenticate_by_token(self, auth_token, roles=None, - include_builtin_token=False): + def authenticate_by_token(self, auth_token, roles=None, include_builtin_token=False): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -614,16 +606,17 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) maybe_builtin = [] if include_builtin_token: - maybe_builtin = [AttributeDict({'api_key': self.api_key})] + maybe_builtin = [AttributeDict({"api_key": self.api_key})] plain_tokens = [] hash_tokens = [] @@ -653,29 +646,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.firstname, self.lastname) - if (self.firstname and self.lastname) else self.username) + return "%s %s" % (self.firstname, self.lastname) if (self.firstname and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -687,8 +679,8 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser - return AuthUser(user_id=self.user_id, api_key=self.api_key, - username=self.username) + + return AuthUser(user_id=self.user_id, api_key=self.api_key, username=self.username) @hybrid_property def user_data(self): @@ -703,32 +695,28 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_user_by_name_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_by_name_%s" % _hash_key(username))) return q.scalar() @@ -737,24 +725,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -762,8 +749,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % _hash_key(email))) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % _hash_key(email))) ret = q.scalar() if ret is None: @@ -775,9 +761,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -789,6 +774,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -807,25 +793,25 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" usr = self old = usr.user_data - old.update({'last_activity': time.time()}) + old.update({"last_activity": time.time()}) usr.user_data = old Session().add(usr) - log.debug('updated user %s lastactivity', usr.username) + log.debug("updated user %s lastactivity", usr.username) def update_password(self, new_password, change_api_key=False): - from rhodecode.lib.auth import get_crypt_password,generate_auth_token + from rhodecode.lib.auth import get_crypt_password, generate_auth_token self.password = get_crypt_password(new_password) if change_api_key: @@ -836,7 +822,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -844,24 +830,24 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -875,85 +861,83 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data api_key_length = 40 - api_key_replacement = '*' * api_key_length + api_key_replacement = "*" * api_key_length extras = { - 'api_key': api_key_replacement, - 'api_keys': [api_key_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "api_key": api_key_replacement, + "api_keys": [api_key_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['api_key'] = user.api_key - data['api_keys'] = user.auth_tokens + data["api_key"] = user.api_key + data["api_keys"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -968,26 +952,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1000,20 +982,18 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_ip_range(cls, ip_addr): @@ -1022,66 +1002,68 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") @hybrid_property def group_data(self): @@ -1101,38 +1083,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1150,7 +1127,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1174,9 +1151,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1186,11 +1165,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1202,205 +1182,184 @@ class UserGroup(Base, BaseModel): user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, } if with_group_members: users = [] for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1409,13 +1368,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1461,13 +1421,11 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_repo_by_name_%s" % _hash_key(repo_name))) + q = q.options(FromCache("sql_cache_short", "get_repo_by_name_%s" % _hash_key(repo_name))) return q.scalar() @@ -1488,8 +1446,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1506,8 +1463,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1549,7 +1505,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1567,8 +1523,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1586,10 +1541,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1606,13 +1558,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1630,7 +1585,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1653,11 +1608,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1682,31 +1638,29 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': url('summary_home', repo_name=self.repo_name, qualified=True), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": url("summary_home", repo_name=self.repo_name, qualified=True), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1754,7 +1708,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1767,40 +1721,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1814,42 +1766,46 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): - qualified_home_url = '/' + qualified_home_url = "/" uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: uri_tmpl = self.DEFAULT_CLONE_URI - return get_clone_url(uri_tmpl=uri_tmpl, - qualifed_home_url=qualified_home_url, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + uri_tmpl=uri_tmpl, + qualifed_home_url=qualified_home_url, + repo_name=self.repo_name, + repo_id=self.repo_id, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -1859,8 +1815,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -1887,12 +1842,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -1900,28 +1855,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -1937,8 +1892,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -1952,19 +1906,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -1984,8 +1933,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -1997,9 +1945,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2012,68 +1960,69 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2084,12 +2033,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [('-1', u'-- %s --' % _('No parent'))] + repo_groups = [("-1", "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2099,26 +2047,20 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @classmethod def get_user_personal_repo_group(cls, user_id): user = User.get(user_id) - return cls.query()\ - .filter(cls.personal == true())\ - .filter(cls.user == user).scalar() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2144,14 +2086,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2175,9 +2120,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2226,15 +2169,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2252,7 +2196,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2276,9 +2220,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2295,115 +2241,104 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.group_description, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.group_description, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2411,9 +2346,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2421,130 +2354,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2556,24 +2468,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2585,42 +2502,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2632,25 +2562,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2662,40 +2608,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2708,21 +2670,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2734,45 +2706,53 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2780,31 +2760,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -2846,13 +2823,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -2863,19 +2840,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -2887,41 +2860,44 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, backref='resolved_by') - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, backref="resolved_by") + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -2932,8 +2908,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -2944,7 +2919,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -2976,33 +2951,32 @@ class ChangesetComment(Base, BaseModel): return self.comment_type == self.COMMENT_TYPE_TODO def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def render(self, mentions=False): from rhodecode.lib import helpers as h + return h.render(self.text, renderer=self.renderer, mentions=mentions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3011,26 +2985,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3047,78 +3018,61 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + target_ref = Column("other_ref", Unicode(255), nullable=False) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3126,9 +3080,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3148,7 +3100,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3159,104 +3111,96 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None def get_api_data(self): from rhodecode.model.pull_request import PullRequestModel + pull_request = self merge_status = PullRequestModel().merge_status(pull_request) pull_request_url = url( - 'pullrequest_show', repo_name=self.target_repo.repo_name, - pull_request_id=self.pull_request_id, qualified=True) + "pullrequest_show", + repo_name=self.target_repo.repo_name, + pull_request_id=self.pull_request_id, + qualified=True, + ) merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': pull_request_url, - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': merge_status[0], - 'message': str(merge_status[1]), + "pull_request_id": pull_request.pull_request_id, + "url": pull_request_url, + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": merge_status[0], + "message": str(merge_status[1]), }, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } for reviewer, reasons, st in pull_request.reviewers_statuses() - ] + ], } return data class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3267,7 +3211,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3275,35 +3219,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3319,49 +3258,47 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(workspace_id) return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -3383,10 +3320,9 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None, reasons=None): @@ -3404,56 +3340,51 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3484,24 +3415,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3509,34 +3445,33 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @classmethod def get_or_404(cls, id_): @@ -3551,11 +3486,12 @@ class Gist(Base, BaseModel): def gist_url(self): import rhodecode - alias_url = rhodecode.CONFIG.get('gist_alias_url') - if alias_url: - return alias_url.replace('{gistid}', self.gist_access_id) - return url('gist', gist_id=self.gist_access_id, qualified=True) + alias_url = rhodecode.CONFIG.get("gist_alias_url") + if alias_url: + return alias_url.replace("{gistid}", self.gist_access_id) + + return url("gist", gist_id=self.gist_access_id, qualified=True) @classmethod def base_path(cls): @@ -3565,8 +3501,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3576,54 +3512,49 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3667,31 +3598,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -3699,90 +3627,87 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_user_id = Column( - 'repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), - nullable=False) - user = relationship('User') + __tablename__ = "repo_review_rules_users" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + user = relationship("User") class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_users_group_id = Column( - 'repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(), - ForeignKey('users_groups.users_group_id'), nullable=False) - users_group = relationship('UserGroup') + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) + users_group = relationship("UserGroup") class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob - use_authors_for_review = Column("use_authors_for_review", Boolean(), - nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_glob(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, branch, files_changed): """ @@ -3792,16 +3717,16 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - branch = branch or '' + branch = branch or "" files_changed = files_changed or [] branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False file_regex = re.compile(glob2re(self.file_pattern)) for filename in files_changed: @@ -3813,12 +3738,10 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = set() - users |= set([ - rule_user.user for rule_user in self.rule_users - if rule_user.user.active]) + users |= set([rule_user.user for rule_user in self.rule_users if rule_user.user.active]) users |= set( member.user for rule_user_group in self.rule_user_groups @@ -3828,33 +3751,30 @@ class RepoReviewRule(Base, BaseModel): return users def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class DbSession(Base, BaseModel): - __tablename__ = 'db_session' + __tablename__ = "db_session" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_7_0_1.py b/rhodecode/lib/dbmigrate/schema/db_4_7_0_1.py index d931b3b8..7e3739eb 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_7_0_1.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_7_0_1.py @@ -35,8 +35,7 @@ import collections from sqlalchemy import * from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from beaker.cache import cache_region from webob.exc import HTTPNotFound @@ -49,9 +48,20 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) + str2bool, + safe_str, + get_commit_safe, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache @@ -59,7 +69,7 @@ from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -74,10 +84,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -89,8 +99,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -107,18 +117,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -126,27 +135,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -157,20 +165,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -181,11 +189,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -240,49 +253,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -292,14 +306,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -311,7 +324,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -322,94 +335,73 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -419,7 +411,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -439,63 +431,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -506,52 +494,60 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + last_activity = Column( + "last_activity", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -568,7 +564,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query().filter(UserEmailMap.user==self).all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).all() return [self.email] + [x.email for x in other] @property @@ -584,30 +580,28 @@ class User(Base, BaseModel): return self.get_feed_token() def get_feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() - def authenticate_by_token(self, auth_token, roles=None, - include_builtin_token=False): + def authenticate_by_token(self, auth_token, roles=None, include_builtin_token=False): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -615,16 +609,17 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) maybe_builtin = [] if include_builtin_token: - maybe_builtin = [AttributeDict({'api_key': self.api_key})] + maybe_builtin = [AttributeDict({"api_key": self.api_key})] plain_tokens = [] hash_tokens = [] @@ -654,29 +649,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.firstname, self.lastname) + return "%s (%s %s)" % (self.username, self.firstname, self.lastname) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def full_name_or_username(self): - return ('%s %s' % (self.firstname, self.lastname) - if (self.firstname and self.lastname) else self.username) + return "%s %s" % (self.firstname, self.lastname) if (self.firstname and self.lastname) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.firstname, self.lastname, self.email) + return "%s %s <%s>" % (self.firstname, self.lastname, self.email) @property def short_contact(self): - return '%s %s' % (self.firstname, self.lastname) + return "%s %s" % (self.firstname, self.lastname) @property def is_admin(self): @@ -688,8 +682,8 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser - return AuthUser(user_id=self.user_id, api_key=self.api_key, - username=self.username) + + return AuthUser(user_id=self.user_id, api_key=self.api_key, username=self.username) @hybrid_property def user_data(self): @@ -704,32 +698,28 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_user_by_name_%s" % _hash_key(username))) + q = q.options(FromCache("sql_cache_short", "get_user_by_name_%s" % _hash_key(username))) return q.scalar() @@ -738,24 +728,23 @@ class User(Base, BaseModel): q = cls.query().filter(cls.api_key == auth_token) if cache: - q = q.options(FromCache("sql_cache_short", - "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) res = q.scalar() if fallback and not res: - #fallback to additional keys - _res = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ + # fallback to additional keys + _res = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) .first() + ) if _res: res = _res.user return res @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -763,8 +752,7 @@ class User(Base, BaseModel): q = cls.query().filter(cls.email == email) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_key_%s" % _hash_key(email))) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % _hash_key(email))) ret = q.scalar() if ret is None: @@ -776,9 +764,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options(FromCache("sql_cache_short", - "get_email_map_key_%s" % email)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email)) + ret = getattr(q.scalar(), "user", None) return ret @@ -790,6 +777,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -808,25 +796,25 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" usr = self old = usr.user_data - old.update({'last_activity': time.time()}) + old.update({"last_activity": time.time()}) usr.user_data = old Session().add(usr) - log.debug('updated user %s lastactivity', usr.username) + log.debug("updated user %s lastactivity", usr.username) def update_password(self, new_password, change_api_key=False): - from rhodecode.lib.auth import get_crypt_password,generate_auth_token + from rhodecode.lib.auth import get_crypt_password, generate_auth_token self.password = get_crypt_password(new_password) if change_api_key: @@ -837,7 +825,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -845,24 +833,24 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -876,85 +864,83 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data api_key_length = 40 - api_key_replacement = '*' * api_key_length + api_key_replacement = "*" * api_key_length extras = { - 'api_key': api_key_replacement, - 'api_keys': [api_key_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "api_key": api_key_replacement, + "api_keys": [api_key_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['api_key'] = user.api_key - data['api_keys'] = user.auth_tokens + data["api_key"] = user.api_key + data["api_keys"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key'), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - UniqueConstraint('api_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key"), + Index("uak_api_key_expires_idx", "api_key", "expires"), + UniqueConstraint("api_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -969,26 +955,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1001,20 +985,18 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @classmethod def _get_ip_range(cls, ip_addr): @@ -1023,66 +1005,68 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) + class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.repository_name, - self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User') + user = relationship("User") @hybrid_property def group_data(self): @@ -1102,38 +1086,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options(FromCache("sql_cache_short", - "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1151,7 +1130,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1175,9 +1154,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1187,11 +1168,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1203,205 +1185,184 @@ class UserGroup(Base, BaseModel): user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, } if with_group_members: users = [] for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1410,13 +1371,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1462,13 +1424,11 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: - q = q.options( - FromCache("sql_cache_short", - "get_repo_by_name_%s" % _hash_key(repo_name))) + q = q.options(FromCache("sql_cache_short", "get_repo_by_name_%s" % _hash_key(repo_name))) return q.scalar() @@ -1489,8 +1449,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1507,8 +1466,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1550,7 +1508,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1568,8 +1526,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1587,10 +1544,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1607,13 +1561,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1631,7 +1588,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1654,11 +1611,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1683,31 +1641,29 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': url('summary_home', repo_name=self.repo_name, qualified=True), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": url("summary_home", repo_name=self.repo_name, qualified=True), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1755,7 +1711,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1768,40 +1724,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1815,42 +1769,46 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): - qualified_home_url = '/' + qualified_home_url = "/" uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: uri_tmpl = self.DEFAULT_CLONE_URI - return get_clone_url(uri_tmpl=uri_tmpl, - qualifed_home_url=qualified_home_url, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + uri_tmpl=uri_tmpl, + qualifed_home_url=qualified_home_url, + repo_name=self.repo_name, + repo_id=self.repo_id, + **override, + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -1860,8 +1818,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -1888,12 +1845,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -1901,28 +1858,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -1938,8 +1895,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -1953,19 +1909,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -1985,8 +1936,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -1998,9 +1948,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2013,68 +1963,69 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, - self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2085,12 +2036,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [('-1', u'-- %s --' % _('No parent'))] + repo_groups = [("-1", "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2100,26 +2050,20 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: - gr = gr.options(FromCache( - "sql_cache_short", - "get_group_%s" % _hash_key(group_name))) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return gr.scalar() @classmethod def get_user_personal_repo_group(cls, user_id): user = User.get(user_id) - return cls.query()\ - .filter(cls.personal == true())\ - .filter(cls.user == user).scalar() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2145,14 +2089,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2176,9 +2123,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2227,15 +2172,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2253,7 +2199,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2277,9 +2223,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2296,115 +2244,104 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.group_description, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.group_description, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2412,9 +2349,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2422,130 +2357,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2557,24 +2471,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2586,42 +2505,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2633,25 +2565,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2663,40 +2611,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2709,21 +2673,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2735,45 +2709,53 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' + __tablename__ = "statistics" __table_args__ = ( - UniqueConstraint('repository_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2781,31 +2763,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -2847,13 +2826,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -2864,19 +2843,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -2888,41 +2863,44 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, backref='resolved_by') - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, backref="resolved_by") + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -2933,8 +2911,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -2945,7 +2922,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -2977,33 +2954,32 @@ class ChangesetComment(Base, BaseModel): return self.comment_type == self.COMMENT_TYPE_TODO def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def render(self, mentions=False): from rhodecode.lib import helpers as h + return h.render(self.text, renderer=self.renderer, mentions=mentions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3012,26 +2988,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3048,78 +3021,61 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + target_ref = Column("other_ref", Unicode(255), nullable=False) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3127,9 +3083,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3149,7 +3103,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3160,104 +3114,96 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None def get_api_data(self): from rhodecode.model.pull_request import PullRequestModel + pull_request = self merge_status = PullRequestModel().merge_status(pull_request) pull_request_url = url( - 'pullrequest_show', repo_name=self.target_repo.repo_name, - pull_request_id=self.pull_request_id, qualified=True) + "pullrequest_show", + repo_name=self.target_repo.repo_name, + pull_request_id=self.pull_request_id, + qualified=True, + ) merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': pull_request_url, - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': { - 'status': merge_status[0], - 'message': str(merge_status[1]), + "pull_request_id": pull_request.pull_request_id, + "url": pull_request_url, + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": { + "status": merge_status[0], + "message": str(merge_status[1]), }, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } for reviewer, reasons, st in pull_request.reviewers_statuses() - ] + ], } return data class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus') - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3268,7 +3214,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3276,35 +3222,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3320,49 +3261,47 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(workspace_id) return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -3384,10 +3323,9 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __init__(self, user=None, pull_request=None, reasons=None): @@ -3405,56 +3343,51 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3485,24 +3418,29 @@ class Notification(Base, BaseModel): @property def description(self): from rhodecode.model.notification import NotificationModel + return NotificationModel().make_description(self) class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3510,34 +3448,33 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @classmethod def get_or_404(cls, id_): @@ -3552,11 +3489,12 @@ class Gist(Base, BaseModel): def gist_url(self): import rhodecode - alias_url = rhodecode.CONFIG.get('gist_alias_url') - if alias_url: - return alias_url.replace('{gistid}', self.gist_access_id) - return url('gist', gist_id=self.gist_access_id, qualified=True) + alias_url = rhodecode.CONFIG.get("gist_alias_url") + if alias_url: + return alias_url.replace("{gistid}", self.gist_access_id) + + return url("gist", gist_id=self.gist_access_id, qualified=True) @classmethod def base_path(cls): @@ -3566,8 +3504,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3577,54 +3515,49 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3668,31 +3601,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -3700,90 +3630,87 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_user_id = Column( - 'repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), - nullable=False) - user = relationship('User') + __tablename__ = "repo_review_rules_users" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + user = relationship("User") class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_users_group_id = Column( - 'repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", - Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(), - ForeignKey('users_groups.users_group_id'), nullable=False) - users_group = relationship('UserGroup') + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) + users_group = relationship("UserGroup") class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), - default=u'*') # glob + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob - use_authors_for_review = Column("use_authors_for_review", Boolean(), - nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_glob(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, branch, files_changed): """ @@ -3793,16 +3720,16 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - branch = branch or '' + branch = branch or "" files_changed = files_changed or [] branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False file_regex = re.compile(glob2re(self.file_pattern)) for filename in files_changed: @@ -3814,12 +3741,10 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = set() - users |= set([ - rule_user.user for rule_user in self.rule_users - if rule_user.user.active]) + users |= set([rule_user.user for rule_user in self.rule_users if rule_user.user.active]) users |= set( member.user for rule_user_group in self.rule_user_groups @@ -3829,33 +3754,30 @@ class RepoReviewRule(Base, BaseModel): return users def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class DbSession(Base, BaseModel): - __tablename__ = 'db_session' + __tablename__ = "db_session" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/schema/db_4_9_0_0.py b/rhodecode/lib/dbmigrate/schema/db_4_9_0_0.py index 4f3c9cc5..4fb75d34 100644 --- a/rhodecode/lib/dbmigrate/schema/db_4_9_0_0.py +++ b/rhodecode/lib/dbmigrate/schema/db_4_9_0_0.py @@ -35,8 +35,7 @@ import collections from sqlalchemy import * from sqlalchemy.ext.declarative import declared_attr from sqlalchemy.ext.hybrid import hybrid_property -from sqlalchemy.orm import ( - relationship, joinedload, class_mapper, validates, aliased) +from sqlalchemy.orm import relationship, joinedload, class_mapper, validates, aliased from sqlalchemy.sql.expression import true from sqlalchemy.sql.functions import coalesce, count # pragma: no cover from beaker.cache import cache_region @@ -47,9 +46,20 @@ from rhodecode.translation import _ from rhodecode.lib.vcs import get_vcs_instance from rhodecode.lib.vcs.backends.base import EmptyCommit, Reference from rhodecode.lib.utils2 import ( - str2bool, safe_str, get_commit_safe, md5_safe, - time_to_datetime, aslist, Optional, safe_int, get_clone_url, AttributeDict, - glob2re, StrictAttributeDict, cleaned_uri) + str2bool, + safe_str, + get_commit_safe, + md5_safe, + time_to_datetime, + aslist, + Optional, + safe_int, + get_clone_url, + AttributeDict, + glob2re, + StrictAttributeDict, + cleaned_uri, +) from rhodecode.lib.jsonalchemy import MutationObj, MutationList, JsonType from rhodecode.lib.ext_json import json from rhodecode.lib.caching_query import FromCache @@ -57,7 +67,7 @@ from rhodecode.lib.encrypt import AESCipher from rhodecode.model.meta import Base, Session -URL_SEP = '/' +URL_SEP = "/" log = logging.getLogger(__name__) # ============================================================================= @@ -72,10 +82,10 @@ ENCRYPTION_KEY = None # used to sort permissions by types, '#' used here is not allowed to be in # usernames, and it's very early in sorted string.printable table. PERMISSION_TYPE_SORT = { - 'admin': '####', - 'write': '###', - 'read': '##', - 'none': '#', + "admin": "####", + "write": "###", + "read": "##", + "none": "#", } @@ -87,8 +97,8 @@ def display_sort(obj): """ if obj.username == User.DEFAULT_USER: - return '#####' - prefix = PERMISSION_TYPE_SORT.get(obj.permission.split('.')[-1], '') + return "#####" + prefix = PERMISSION_TYPE_SORT.get(obj.permission.split(".")[-1], "") return prefix + obj.username @@ -105,18 +115,17 @@ class EncryptedTextValue(TypeDecorator): This column is intelligent so if value is in unencrypted form it return unencrypted form, but on save it always encrypts """ + impl = Text def process_bind_param(self, value, dialect): if not value: return value - if value.startswith('enc$aes$') or value.startswith('enc$aes_hmac$'): + if value.startswith("enc$aes$") or value.startswith("enc$aes_hmac$"): # protect against double encrypting if someone manually starts # doing - raise ValueError('value needs to be in unencrypted format, ie. ' - 'not starting with enc$aes') - return 'enc$aes_hmac$%s' % AESCipher( - ENCRYPTION_KEY, hmac=True).encrypt(value) + raise ValueError("value needs to be in unencrypted format, ie. not starting with enc$aes") + return "enc$aes_hmac$%s" % AESCipher(ENCRYPTION_KEY, hmac=True).encrypt(value) def process_result_value(self, value, dialect): import rhodecode @@ -124,27 +133,26 @@ class EncryptedTextValue(TypeDecorator): if not value: return value - parts = value.split('$', 3) + parts = value.split("$", 3) if not len(parts) == 3: # probably not encrypted values return value else: - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header ? return value - enc_strict_mode = str2bool(rhodecode.CONFIG.get( - 'rhodecode.encrypted_values.strict') or True) + enc_strict_mode = str2bool(rhodecode.CONFIG.get("rhodecode.encrypted_values.strict") or True) # at that stage we know it's our encryption - if parts[1] == 'aes': + if parts[1] == "aes": decrypted_data = AESCipher(ENCRYPTION_KEY).decrypt(parts[2]) - elif parts[1] == 'aes_hmac': - decrypted_data = AESCipher( - ENCRYPTION_KEY, hmac=True, - strict_verification=enc_strict_mode).decrypt(parts[2]) + elif parts[1] == "aes_hmac": + decrypted_data = AESCipher(ENCRYPTION_KEY, hmac=True, strict_verification=enc_strict_mode).decrypt( + parts[2] + ) else: raise ValueError( - 'Encryption type part is wrong, must be `aes` ' - 'or `aes_hmac`, got `%s` instead' % (parts[1])) + "Encryption type part is wrong, must be `aes` or `aes_hmac`, got `%s` instead" % (parts[1]) + ) return decrypted_data @@ -155,20 +163,20 @@ class BaseModel(object): @classmethod def _get_keys(cls): - """return column names for this model """ + """return column names for this model""" return class_mapper(cls).c.keys() def get_dict(self): """ return dict with keys and values corresponding - to this model data """ + to this model data""" d = {} for k in self._get_keys(): d[k] = getattr(self, k) # also use __json__() if present to get additional fields - _json_attr = getattr(self, '__json__', None) + _json_attr = getattr(self, "__json__", None) if _json_attr: # update with attributes from __json__ if callable(_json_attr): @@ -179,11 +187,16 @@ class BaseModel(object): def get_appstruct(self): """return list with keys and values tuples corresponding - to this model data """ + to this model data""" l = [] for k in self._get_keys(): - l.append((k, getattr(self, k),)) + l.append( + ( + k, + getattr(self, k), + ) + ) return l def populate_obj(self, populate_dict): @@ -240,49 +253,50 @@ class BaseModel(object): if len(exist_in_session) == 1: return exist_in_session[0] log.exception( - 'multiple objects with attr %s and ' - 'value %s found with same name: %r', - attr_name, value, exist_in_session) + "multiple objects with attr %s and value %s found with same name: %r", + attr_name, + value, + exist_in_session, + ) def __repr__(self): - if hasattr(self, '__unicode__'): + if hasattr(self, "__unicode__"): # python repr needs to return str try: return safe_str(self.__unicode__()) except UnicodeDecodeError: pass - return '' % (self.__class__.__name__) + return "" % (self.__class__.__name__) class RhodeCodeSetting(Base, BaseModel): - __tablename__ = 'rhodecode_settings' + __tablename__ = "rhodecode_settings" __table_args__ = ( - UniqueConstraint('app_settings_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) SETTINGS_TYPES = { - 'str': safe_str, - 'int': safe_int, - 'unicode': safe_str, - 'bool': str2bool, - 'list': functools.partial(aslist, sep=',') + "str": safe_str, + "int": safe_int, + "unicode": safe_str, + "bool": str2bool, + "list": functools.partial(aslist, sep=","), } - DEFAULT_UPDATE_URL = 'https://rhodecode.com/api/v1/info/versions' - GLOBAL_CONF_KEY = 'app_settings' + DEFAULT_UPDATE_URL = "https://rhodecode.com/api/v1/info/versions" + GLOBAL_CONF_KEY = "app_settings" app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - def __init__(self, key='', val='', type='unicode'): + def __init__(self, key="", val="", type="unicode"): self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -292,14 +306,13 @@ class RhodeCodeSetting(Base, BaseModel): v = self._app_settings_value _type = self.app_settings_type if _type: - _type = self.app_settings_type.split('.')[0] + _type = self.app_settings_type.split(".")[0] # decode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() v = safe_str(cipher.process_result_value(v, None)) - converter = self.SETTINGS_TYPES.get(_type) or \ - self.SETTINGS_TYPES['unicode'] + converter = self.SETTINGS_TYPES.get(_type) or self.SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -311,7 +324,7 @@ class RhodeCodeSetting(Base, BaseModel): """ val = safe_str(val) # encode the encrypted value - if 'encrypted' in self.app_settings_type: + if "encrypted" in self.app_settings_type: cipher = EncryptedTextValue() val = safe_str(cipher.process_bind_param(val, None)) self._app_settings_value = val @@ -322,95 +335,74 @@ class RhodeCodeSetting(Base, BaseModel): @app_settings_type.setter def app_settings_type(self, val): - if val.split('.')[0] not in self.SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (self.SETTINGS_TYPES.keys(), val)) + if val.split(".")[0] not in self.SETTINGS_TYPES: + raise Exception("type must be one of %s got %s" % (self.SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( + return "<%s('%s:%s[%s]')>" % ( self.__class__.__name__, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RhodeCodeUi(Base, BaseModel): - __tablename__ = 'rhodecode_ui' + __tablename__ = "rhodecode_ui" __table_args__ = ( - UniqueConstraint('ui_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("ui_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - HOOK_REPO_SIZE = 'changegroup.repo_size' + HOOK_REPO_SIZE = "changegroup.repo_size" # HG - HOOK_PRE_PULL = 'preoutgoing.pre_pull' - HOOK_PULL = 'outgoing.pull_logger' - HOOK_PRE_PUSH = 'prechangegroup.pre_push' - HOOK_PRETX_PUSH = 'pretxnchangegroup.pre_push' - HOOK_PUSH = 'changegroup.push_logger' - HOOK_PUSH_KEY = 'pushkey.key_push' + HOOK_PRE_PULL = "preoutgoing.pre_pull" + HOOK_PULL = "outgoing.pull_logger" + HOOK_PRE_PUSH = "prechangegroup.pre_push" + HOOK_PRETX_PUSH = "pretxnchangegroup.pre_push" + HOOK_PUSH = "changegroup.push_logger" + HOOK_PUSH_KEY = "pushkey.key_push" # TODO: johbo: Unify way how hooks are configured for git and hg, # git part is currently hardcoded. # SVN PATTERNS - SVN_BRANCH_ID = 'vcs_svn_branch' - SVN_TAG_ID = 'vcs_svn_tag' + SVN_BRANCH_ID = "vcs_svn_branch" + SVN_TAG_ID = "vcs_svn_tag" - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) def __repr__(self): - return '<%s[%s]%s=>%s]>' % (self.__class__.__name__, self.ui_section, - self.ui_key, self.ui_value) + return "<%s[%s]%s=>%s]>" % (self.__class__.__name__, self.ui_section, self.ui_key, self.ui_value) class RepoRhodeCodeSetting(Base, BaseModel): - __tablename__ = 'repo_rhodecode_settings' + __tablename__ = "repo_rhodecode_settings" __table_args__ = ( - UniqueConstraint( - 'app_settings_name', 'repository_id', - name='uq_repo_rhodecode_setting_name_repo_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("app_settings_name", "repository_id", name="uq_repo_rhodecode_setting_name_repo_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - app_settings_id = Column( - "app_settings_id", Integer(), nullable=False, unique=True, - default=None, primary_key=True) - app_settings_name = Column( - "app_settings_name", String(255), nullable=True, unique=None, - default=None) - _app_settings_value = Column( - "app_settings_value", String(4096), nullable=True, unique=None, - default=None) - _app_settings_type = Column( - "app_settings_type", String(255), nullable=True, unique=None, - default=None) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + app_settings_name = Column("app_settings_name", String(255), nullable=True, unique=None, default=None) + _app_settings_value = Column("app_settings_value", String(4096), nullable=True, unique=None, default=None) + _app_settings_type = Column("app_settings_type", String(255), nullable=True, unique=None, default=None) - repository = relationship('Repository') + repository = relationship("Repository") - def __init__(self, repository_id, key='', val='', type='unicode'): + def __init__(self, repository_id, key="", val="", type="unicode"): self.repository_id = repository_id self.app_settings_name = key self.app_settings_type = type self.app_settings_value = val - @validates('_app_settings_value') + @validates("_app_settings_value") def validate_settings_value(self, key, val): assert type(val) == str return val @@ -420,7 +412,7 @@ class RepoRhodeCodeSetting(Base, BaseModel): v = self._app_settings_value type_ = self.app_settings_type SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES - converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES['unicode'] + converter = SETTINGS_TYPES.get(type_) or SETTINGS_TYPES["unicode"] return converter(v) @app_settings_value.setter @@ -440,63 +432,59 @@ class RepoRhodeCodeSetting(Base, BaseModel): def app_settings_type(self, val): SETTINGS_TYPES = RhodeCodeSetting.SETTINGS_TYPES if val not in SETTINGS_TYPES: - raise Exception('type must be one of %s got %s' - % (SETTINGS_TYPES.keys(), val)) + raise Exception("type must be one of %s got %s" % (SETTINGS_TYPES.keys(), val)) self._app_settings_type = val def __unicode__(self): - return u"<%s('%s:%s:%s[%s]')>" % ( - self.__class__.__name__, self.repository.repo_name, - self.app_settings_name, self.app_settings_value, - self.app_settings_type + return "<%s('%s:%s:%s[%s]')>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.app_settings_name, + self.app_settings_value, + self.app_settings_type, ) class RepoRhodeCodeUi(Base, BaseModel): - __tablename__ = 'repo_rhodecode_ui' + __tablename__ = "repo_rhodecode_ui" __table_args__ = ( UniqueConstraint( - 'repository_id', 'ui_section', 'ui_key', - name='uq_repo_rhodecode_ui_repository_id_section_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + "repository_id", "ui_section", "ui_key", name="uq_repo_rhodecode_ui_repository_id_section_key" + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column( - "repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False) - ui_id = Column( - "ui_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - ui_section = Column( - "ui_section", String(255), nullable=True, unique=None, default=None) - ui_key = Column( - "ui_key", String(255), nullable=True, unique=None, default=None) - ui_value = Column( - "ui_value", String(255), nullable=True, unique=None, default=None) - ui_active = Column( - "ui_active", Boolean(), nullable=True, unique=None, default=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ui_section = Column("ui_section", String(255), nullable=True, unique=None, default=None) + ui_key = Column("ui_key", String(255), nullable=True, unique=None, default=None) + ui_value = Column("ui_value", String(255), nullable=True, unique=None, default=None) + ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) - repository = relationship('Repository') + repository = relationship("Repository") def __repr__(self): - return '<%s[%s:%s]%s=>%s]>' % ( - self.__class__.__name__, self.repository.repo_name, - self.ui_section, self.ui_key, self.ui_value) + return "<%s[%s:%s]%s=>%s]>" % ( + self.__class__.__name__, + self.repository.repo_name, + self.ui_section, + self.ui_key, + self.ui_value, + ) class User(Base, BaseModel): - __tablename__ = 'users' + __tablename__ = "users" __table_args__ = ( - UniqueConstraint('username'), UniqueConstraint('email'), - Index('u_username_idx', 'username'), - Index('u_email_idx', 'email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("username"), + UniqueConstraint("email"), + Index("u_username_idx", "username"), + Index("u_email_idx", "email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_USER = 'default' - DEFAULT_USER_EMAIL = 'anonymous@rhodecode.org' - DEFAULT_GRAVATAR_URL = 'https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}' + DEFAULT_USER = "default" + DEFAULT_USER_EMAIL = "anonymous@rhodecode.org" + DEFAULT_GRAVATAR_URL = "https://secure.gravatar.com/avatar/{md5email}?d=identicon&s={size}" user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) username = Column("username", String(255), nullable=True, unique=None, default=None) @@ -507,55 +495,61 @@ class User(Base, BaseModel): lastname = Column("lastname", String(255), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=None, default=None) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) - last_activity = Column('last_activity', DateTime(timezone=False), nullable=True, unique=None, default=None) + last_activity = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None, default=None) extern_type = Column("extern_type", String(255), nullable=True, unique=None, default=None) extern_name = Column("extern_name", String(255), nullable=True, unique=None, default=None) _api_key = Column("api_key", String(255), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _user_data = Column("user_data", LargeBinary(), nullable=True) # JSON data - user_log = relationship('UserLog') - user_perms = relationship('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relationship("UserLog") + user_perms = relationship("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relationship('Repository') - repository_groups = relationship('RepoGroup') - user_groups = relationship('UserGroup') + repositories = relationship("Repository") + repository_groups = relationship("RepoGroup") + user_groups = relationship("UserGroup") - user_followers = relationship('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') - followings = relationship('UserFollowing', primaryjoin='UserFollowing.user_id==User.user_id', cascade='all') + user_followers = relationship( + "UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all" + ) + followings = relationship("UserFollowing", primaryjoin="UserFollowing.user_id==User.user_id", cascade="all") - repo_to_perm = relationship('UserRepoToPerm', primaryjoin='UserRepoToPerm.user_id==User.user_id', cascade='all') - repo_group_to_perm = relationship('UserRepoGroupToPerm', primaryjoin='UserRepoGroupToPerm.user_id==User.user_id', cascade='all') - user_group_to_perm = relationship('UserUserGroupToPerm', primaryjoin='UserUserGroupToPerm.user_id==User.user_id', cascade='all') + repo_to_perm = relationship("UserRepoToPerm", primaryjoin="UserRepoToPerm.user_id==User.user_id", cascade="all") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", primaryjoin="UserRepoGroupToPerm.user_id==User.user_id", cascade="all" + ) + user_group_to_perm = relationship( + "UserUserGroupToPerm", primaryjoin="UserUserGroupToPerm.user_id==User.user_id", cascade="all" + ) - group_member = relationship('UserGroupMember', cascade='all') + group_member = relationship("UserGroupMember", cascade="all") - notifications = relationship('UserNotification', cascade='all') + notifications = relationship("UserNotification", cascade="all") # notifications assigned to this user - user_created_notifications = relationship('Notification', cascade='all') + user_created_notifications = relationship("Notification", cascade="all") # comments created by this user - user_comments = relationship('ChangesetComment', cascade='all') + user_comments = relationship("ChangesetComment", cascade="all") # user profile extra info - user_emails = relationship('UserEmailMap', cascade='all') - user_ip_map = relationship('UserIpMap', cascade='all') - user_auth_tokens = relationship('UserApiKeys', cascade='all') - user_ssh_keys = relationship('UserSshKeys', cascade='all') + user_emails = relationship("UserEmailMap", cascade="all") + user_ip_map = relationship("UserIpMap", cascade="all") + user_auth_tokens = relationship("UserApiKeys", cascade="all") + user_ssh_keys = relationship("UserSshKeys", cascade="all") # gists - user_gists = relationship('Gist', cascade='all') + user_gists = relationship("Gist", cascade="all") # user pull requests - user_pull_requests = relationship('PullRequest', cascade='all') + user_pull_requests = relationship("PullRequest", cascade="all") # external identities extenal_identities = relationship( - 'ExternalIdentity', - primaryjoin="User.user_id==ExternalIdentity.local_user_id", - cascade='all') + "ExternalIdentity", primaryjoin="User.user_id==ExternalIdentity.local_user_id", cascade="all" + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.user_id, self.username) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.user_id, self.username) @hybrid_property def email(self): @@ -568,6 +562,7 @@ class User(Base, BaseModel): @hybrid_property def first_name(self): from rhodecode.lib import helpers as h + if self.name: return h.escape(self.name) return self.name @@ -575,6 +570,7 @@ class User(Base, BaseModel): @hybrid_property def last_name(self): from rhodecode.lib import helpers as h + if self.lastname: return h.escape(self.lastname) return self.lastname @@ -584,11 +580,13 @@ class User(Base, BaseModel): """ Fetch if exist an auth-token with role ALL connected to this user """ - user_auth_token = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time()))\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL).first() + user_auth_token = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + .filter(UserApiKeys.role == UserApiKeys.ROLE_ALL) + .first() + ) if user_auth_token: user_auth_token = user_auth_token.api_key @@ -601,10 +599,12 @@ class User(Base, BaseModel): @property def reviewer_pull_requests(self): - return PullRequestReviewers.query() \ - .options(joinedload(PullRequestReviewers.pull_request)) \ - .filter(PullRequestReviewers.user_id == self.user_id) \ + return ( + PullRequestReviewers.query() + .options(joinedload(PullRequestReviewers.pull_request)) + .filter(PullRequestReviewers.user_id == self.user_id) .all() + ) @property def firstname(self): @@ -613,10 +613,7 @@ class User(Base, BaseModel): @property def emails(self): - other = UserEmailMap.query()\ - .filter(UserEmailMap.user == self) \ - .order_by(UserEmailMap.email_id.asc()) \ - .all() + other = UserEmailMap.query().filter(UserEmailMap.user == self).order_by(UserEmailMap.email_id.asc()).all() return [self.email] + [x.email for x in other] @property @@ -625,39 +622,35 @@ class User(Base, BaseModel): return [x.api_key for x in auth_tokens] def get_auth_tokens(self): - return UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .order_by(UserApiKeys.user_api_key_id.asc())\ - .all() + return UserApiKeys.query().filter(UserApiKeys.user == self).order_by(UserApiKeys.user_api_key_id.asc()).all() @property def feed_token(self): return self.get_feed_token() def get_feed_token(self): - feed_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ - .filter(UserApiKeys.role == UserApiKeys.ROLE_FEED)\ - .all() + feed_tokens = ( + UserApiKeys.query().filter(UserApiKeys.user == self).filter(UserApiKeys.role == UserApiKeys.ROLE_FEED).all() + ) if feed_tokens: return feed_tokens[0].api_key - return 'NO_FEED_TOKEN_AVAILABLE' + return "NO_FEED_TOKEN_AVAILABLE" @classmethod def extra_valid_auth_tokens(cls, user, role=None): - tokens = UserApiKeys.query().filter(UserApiKeys.user == user)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens = ( + UserApiKeys.query() + .filter(UserApiKeys.user == user) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if role: - tokens = tokens.filter(or_(UserApiKeys.role == role, - UserApiKeys.role == UserApiKeys.ROLE_ALL)) + tokens = tokens.filter(or_(UserApiKeys.role == role, UserApiKeys.role == UserApiKeys.ROLE_ALL)) return tokens.all() def authenticate_by_token(self, auth_token, roles=None, scope_repo_id=None): from rhodecode.lib import auth - log.debug('Trying to authenticate user: %s via auth-token, ' - 'and roles: %s', self, roles) + log.debug("Trying to authenticate user: %s via auth-token, and roles: %s", self, roles) if not auth_token: return False @@ -665,10 +658,11 @@ class User(Base, BaseModel): crypto_backend = auth.crypto_backend() roles = (roles or []) + [UserApiKeys.ROLE_ALL] - tokens_q = UserApiKeys.query()\ - .filter(UserApiKeys.user_id == self.user_id)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + tokens_q = ( + UserApiKeys.query() + .filter(UserApiKeys.user_id == self.user_id) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) tokens_q = tokens_q.filter(UserApiKeys.role.in_(roles)) @@ -681,9 +675,11 @@ class User(Base, BaseModel): # token has a scope, we need to verify it if scope_repo_id != token.repo_id: log.debug( - 'Scope mismatch: token has a set repo scope: %s, ' - 'and calling scope is:%s, skipping further checks', - token.repo, scope_repo_id) + "Scope mismatch: token has a set repo scope: %s, " + "and calling scope is:%s, skipping further checks", + token.repo, + scope_repo_id, + ) # token has a scope, and it doesn't match, skip token continue @@ -711,29 +707,28 @@ class User(Base, BaseModel): @property def username_and_name(self): - return '%s (%s %s)' % (self.username, self.first_name, self.last_name) + return "%s (%s %s)" % (self.username, self.first_name, self.last_name) @property def username_or_name_or_email(self): - full_name = self.full_name if self.full_name is not ' ' else None + full_name = self.full_name if self.full_name is not " " else None return self.username or full_name or self.email @property def full_name(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def full_name_or_username(self): - return ('%s %s' % (self.first_name, self.last_name) - if (self.first_name and self.last_name) else self.username) + return "%s %s" % (self.first_name, self.last_name) if (self.first_name and self.last_name) else self.username @property def full_contact(self): - return '%s %s <%s>' % (self.first_name, self.last_name, self.email) + return "%s %s <%s>" % (self.first_name, self.last_name, self.email) @property def short_contact(self): - return '%s %s' % (self.first_name, self.last_name) + return "%s %s" % (self.first_name, self.last_name) @property def is_admin(self): @@ -745,6 +740,7 @@ class User(Base, BaseModel): Returns instance of AuthUser for this user """ from rhodecode.lib.auth import AuthUser + return AuthUser(user_id=self.user_id, username=self.username) @hybrid_property @@ -760,44 +756,41 @@ class User(Base, BaseModel): @user_data.setter def user_data(self, val): if not isinstance(val, dict): - raise Exception('user_data must be dict, got %s' % type(val)) + raise Exception("user_data must be dict, got %s" % type(val)) try: self._user_data = json.dumps(val) except Exception: log.error(traceback.format_exc()) @classmethod - def get_by_username(cls, username, case_insensitive=False, - cache=False, identity_cache=False): + def get_by_username(cls, username, case_insensitive=False, cache=False, identity_cache=False): session = Session() if case_insensitive: - q = cls.query().filter( - func.lower(cls.username) == func.lower(username)) + q = cls.query().filter(func.lower(cls.username) == func.lower(username)) else: q = cls.query().filter(cls.username == username) if cache: if identity_cache: - val = cls.identity_cache(session, 'username', username) + val = cls.identity_cache(session, "username", username) if val: return val else: cache_key = "get_user_by_name_%s" % _hash_key(username) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @classmethod def get_by_auth_token(cls, auth_token, cache=False): - q = UserApiKeys.query()\ - .filter(UserApiKeys.api_key == auth_token)\ - .filter(or_(UserApiKeys.expires == -1, - UserApiKeys.expires >= time.time())) + q = ( + UserApiKeys.query() + .filter(UserApiKeys.api_key == auth_token) + .filter(or_(UserApiKeys.expires == -1, UserApiKeys.expires >= time.time())) + ) if cache: - q = q.options( - FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) + q = q.options(FromCache("sql_cache_short", "get_auth_token_%s" % auth_token)) match = q.first() if match: @@ -805,7 +798,6 @@ class User(Base, BaseModel): @classmethod def get_by_email(cls, email, case_insensitive=False, cache=False): - if case_insensitive: q = cls.query().filter(func.lower(cls.email) == func.lower(email)) @@ -814,8 +806,7 @@ class User(Base, BaseModel): email_key = _hash_key(email) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_key_%s" % email_key)) + q = q.options(FromCache("sql_cache_short", "get_email_key_%s" % email_key)) ret = q.scalar() if ret is None: @@ -827,9 +818,8 @@ class User(Base, BaseModel): q = q.filter(UserEmailMap.email == email) q = q.options(joinedload(UserEmailMap.user)) if cache: - q = q.options( - FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) - ret = getattr(q.scalar(), 'user', None) + q = q.options(FromCache("sql_cache_short", "get_email_map_key_%s" % email_key)) + ret = getattr(q.scalar(), "user", None) return ret @@ -841,6 +831,7 @@ class User(Base, BaseModel): :param author: """ from rhodecode.lib.helpers import email, author_name + # Valid email in the attribute passed, see if they're in the system _email = email(author) if _email: @@ -859,19 +850,19 @@ class User(Base, BaseModel): old.update(**kwargs) usr.user_data = old Session().add(usr) - log.debug('updated userdata with ', kwargs) + log.debug("updated userdata with ", kwargs) def update_lastlogin(self): """Update user lastlogin""" self.last_login = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) def update_lastactivity(self): """Update user lastactivity""" self.last_activity = datetime.datetime.now() Session().add(self) - log.debug('updated user %s lastactivity', self.username) + log.debug("updated user %s lastactivity", self.username) def update_password(self, new_password): from rhodecode.lib.auth import get_crypt_password @@ -883,7 +874,7 @@ class User(Base, BaseModel): def get_first_super_admin(cls): user = User.query().filter(User.admin == true()).first() if user is None: - raise Exception('FATAL: Missing administrative account!') + raise Exception("FATAL: Missing administrative account!") return user @classmethod @@ -891,14 +882,13 @@ class User(Base, BaseModel): """ Returns all admin accounts sorted by username """ - return User.query().filter(User.admin == true())\ - .order_by(User.username.asc()).all() + return User.query().filter(User.admin == true()).order_by(User.username.asc()).all() @classmethod def get_default_user(cls, cache=False, refresh=False): user = User.get_by_username(User.DEFAULT_USER, cache=cache) if user is None: - raise Exception('FATAL: Missing default account!') + raise Exception("FATAL: Missing default account!") if refresh: # The default user might be based on outdated state which # has been loaded from the cache. @@ -907,14 +897,15 @@ class User(Base, BaseModel): Session().refresh(user) return user - def _get_default_perms(self, user, suffix=''): + def _get_default_perms(self, user, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user.user_perms, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) - def get_api_data(self, include_secrets=False, details='full'): + def get_api_data(self, include_secrets=False, details="full"): """ Common function for generating user related data for API @@ -928,97 +919,89 @@ class User(Base, BaseModel): user = self user_data = self.user_data data = { - 'user_id': user.user_id, - 'username': user.username, - 'firstname': user.name, - 'lastname': user.lastname, - 'email': user.email, - 'emails': user.emails, + "user_id": user.user_id, + "username": user.username, + "firstname": user.name, + "lastname": user.lastname, + "email": user.email, + "emails": user.emails, } - if details == 'basic': + if details == "basic": return data auth_token_length = 40 - auth_token_replacement = '*' * auth_token_length + auth_token_replacement = "*" * auth_token_length extras = { - 'auth_tokens': [auth_token_replacement], - 'active': user.active, - 'admin': user.admin, - 'extern_type': user.extern_type, - 'extern_name': user.extern_name, - 'last_login': user.last_login, - 'last_activity': user.last_activity, - 'ip_addresses': user.ip_addresses, - 'language': user_data.get('language') + "auth_tokens": [auth_token_replacement], + "active": user.active, + "admin": user.admin, + "extern_type": user.extern_type, + "extern_name": user.extern_name, + "last_login": user.last_login, + "last_activity": user.last_activity, + "ip_addresses": user.ip_addresses, + "language": user_data.get("language"), } data.update(extras) if include_secrets: - data['auth_tokens'] = user.auth_tokens + data["auth_tokens"] = user.auth_tokens return data def __json__(self): data = { - 'full_name': self.full_name, - 'full_name_or_username': self.full_name_or_username, - 'short_contact': self.short_contact, - 'full_contact': self.full_contact, + "full_name": self.full_name, + "full_name_or_username": self.full_name_or_username, + "short_contact": self.short_contact, + "full_contact": self.full_contact, } data.update(self.get_api_data()) return data class UserApiKeys(Base, BaseModel): - __tablename__ = 'user_api_keys' + __tablename__ = "user_api_keys" __table_args__ = ( - Index('uak_api_key_idx', 'api_key', unique=True), - Index('uak_api_key_expires_idx', 'api_key', 'expires'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uak_api_key_idx", "api_key", unique=True), + Index("uak_api_key_expires_idx", "api_key", "expires"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) # ApiKey role - ROLE_ALL = 'token_role_all' - ROLE_HTTP = 'token_role_http' - ROLE_VCS = 'token_role_vcs' - ROLE_API = 'token_role_api' - ROLE_FEED = 'token_role_feed' - ROLE_PASSWORD_RESET = 'token_password_reset' + ROLE_ALL = "token_role_all" + ROLE_HTTP = "token_role_http" + ROLE_VCS = "token_role_vcs" + ROLE_API = "token_role_api" + ROLE_FEED = "token_role_feed" + ROLE_PASSWORD_RESET = "token_password_reset" ROLES = [ROLE_ALL, ROLE_HTTP, ROLE_VCS, ROLE_API, ROLE_FEED] user_api_key_id = Column("user_api_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) api_key = Column("api_key", String(255), nullable=False, unique=True) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - expires = Column('expires', Float(53), nullable=False) - role = Column('role', String(255), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + expires = Column("expires", Float(53), nullable=False) + role = Column("role", String(255), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) # scope columns - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __unicode__(self): - return u"<%s('%s')>" % (self.__class__.__name__, self.role) + return "<%s('%s')>" % (self.__class__.__name__, self.role) def __json__(self): - data = { - 'auth_token': self.api_key, - 'role': self.role, - 'scope': self.scope_humanized, - 'expired': self.expired - } + data = {"auth_token": self.api_key, "role": self.role, "scope": self.scope_humanized, "expired": self.expired} return data def get_api_data(self, include_secrets=False): @@ -1026,12 +1009,13 @@ class UserApiKeys(Base, BaseModel): if include_secrets: return data else: - data['auth_token'] = self.token_obfuscated + data["auth_token"] = self.token_obfuscated return data @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @property @@ -1043,11 +1027,11 @@ class UserApiKeys(Base, BaseModel): @classmethod def _get_role_name(cls, role): return { - cls.ROLE_ALL: _('all'), - cls.ROLE_HTTP: _('http/web interface'), - cls.ROLE_VCS: _('vcs (git/hg/svn protocol)'), - cls.ROLE_API: _('api calls'), - cls.ROLE_FEED: _('feed access'), + cls.ROLE_ALL: _("all"), + cls.ROLE_HTTP: _("http/web interface"), + cls.ROLE_VCS: _("vcs (git/hg/svn protocol)"), + cls.ROLE_API: _("api calls"), + cls.ROLE_FEED: _("feed access"), }.get(role, role) @property @@ -1058,8 +1042,8 @@ class UserApiKeys(Base, BaseModel): if self.repo: return repr(self.repo) if self.repo_group: - return repr(self.repo_group) + ' (recursive)' - return 'global' + return repr(self.repo_group) + " (recursive)" + return "global" @property def scope_humanized(self): @@ -1072,25 +1056,24 @@ class UserApiKeys(Base, BaseModel): class UserEmailMap(Base, BaseModel): - __tablename__ = 'user_email_map' + __tablename__ = "user_email_map" __table_args__ = ( - Index('uem_email_idx', 'email'), - UniqueConstraint('email'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("uem_email_idx", "email"), + UniqueConstraint("email"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) email_id = Column("email_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) _email = Column("email", String(255), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") - @validates('_email') + @validates("_email") def validate_email(self, key, email): # check if this email is not main one main_email = Session().query(User).filter(User.email == email).scalar() if main_email is not None: - raise AttributeError('email %s is present is user table' % email) + raise AttributeError("email %s is present is user table" % email) return email @hybrid_property @@ -1103,23 +1086,23 @@ class UserEmailMap(Base, BaseModel): class UserIpMap(Base, BaseModel): - __tablename__ = 'user_ip_map' + __tablename__ = "user_ip_map" __table_args__ = ( - UniqueConstraint('user_id', 'ip_addr'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "ip_addr"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) ip_id = Column("ip_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) ip_addr = Column("ip_addr", String(255), nullable=True, unique=False, default=None) active = Column("active", Boolean(), nullable=True, unique=None, default=True) description = Column("description", String(10000), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @classmethod @@ -1129,43 +1112,39 @@ class UserIpMap(Base, BaseModel): def __json__(self): return { - 'ip_addr': self.ip_addr, - 'ip_range': self._get_ip_range(self.ip_addr), + "ip_addr": self.ip_addr, + "ip_range": self._get_ip_range(self.ip_addr), } def __unicode__(self): - return u"<%s('user_id:%s=>%s')>" % (self.__class__.__name__, - self.user_id, self.ip_addr) + return "<%s('user_id:%s=>%s')>" % (self.__class__.__name__, self.user_id, self.ip_addr) class UserSshKeys(Base, BaseModel): - __tablename__ = 'user_ssh_keys' + __tablename__ = "user_ssh_keys" __table_args__ = ( - Index('usk_ssh_key_fingerprint_idx', 'ssh_key_fingerprint'), - UniqueConstraint('ssh_key_fingerprint'), - - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("usk_ssh_key_fingerprint_idx", "ssh_key_fingerprint"), + UniqueConstraint("ssh_key_fingerprint"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - - ssh_key_id = Column('ssh_key_id', Integer(), nullable=False, unique=True, default=None, primary_key=True) - ssh_key_data = Column('ssh_key_data', String(10240), nullable=False, unique=None, default=None) - ssh_key_fingerprint = Column('ssh_key_fingerprint', String(255), nullable=False, unique=None, default=None) + ssh_key_id = Column("ssh_key_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + ssh_key_data = Column("ssh_key_data", String(10240), nullable=False, unique=None, default=None) + ssh_key_fingerprint = Column("ssh_key_fingerprint", String(255), nullable=False, unique=None, default=None) - description = Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) + description = Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - accessed_on = Column('accessed_on', DateTime(timezone=False), nullable=True, default=None) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + accessed_on = Column("accessed_on", DateTime(timezone=False), nullable=True, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) - user = relationship('User', lazy='joined') + user = relationship("User", lazy="joined") def __json__(self): data = { - 'ssh_fingerprint': self.ssh_key_fingerprint, - 'description': self.description, - 'created_on': self.created_on + "ssh_fingerprint": self.ssh_key_fingerprint, + "description": self.description, + "created_on": self.created_on, } return data @@ -1175,75 +1154,80 @@ class UserSshKeys(Base, BaseModel): class UserLog(Base, BaseModel): - __tablename__ = 'user_logs' + __tablename__ = "user_logs" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - VERSION_1 = 'v1' - VERSION_2 = 'v2' + VERSION_1 = "v1" + VERSION_2 = "v2" VERSIONS = [VERSION_1, VERSION_2] user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None) username = Column("username", String(255), nullable=True, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True) + repository_id = Column("repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True) repository_name = Column("repository_name", String(255), nullable=True, unique=None, default=None) user_ip = Column("user_ip", String(255), nullable=True, unique=None, default=None) - action = Column("action", Text().with_variant(Text(1200000), 'mysql'), nullable=True, unique=None, default=None) + action = Column("action", Text().with_variant(Text(1200000), "mysql"), nullable=True, unique=None, default=None) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) version = Column("version", String(255), nullable=True, default=VERSION_1) - user_data = Column('user_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - action_data = Column('action_data_json', MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + user_data = Column("user_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + action_data = Column( + "action_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.repository_name, self.action) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.repository_name, self.action) def __json__(self): return { - 'user_id': self.user_id, - 'username': self.username, - 'repository_id': self.repository_id, - 'repository_name': self.repository_name, - 'user_ip': self.user_ip, - 'action_date': self.action_date, - 'action': self.action, + "user_id": self.user_id, + "username": self.username, + "repository_id": self.repository_id, + "repository_name": self.repository_name, + "user_ip": self.user_ip, + "action_date": self.action_date, + "action": self.action, } @property def action_as_day(self): return datetime.date(*self.action_date.timetuple()[:3]) - user = relationship('User') - repository = relationship('Repository', cascade='') + user = relationship("User") + repository = relationship("Repository", cascade="") class UserGroup(Base, BaseModel): - __tablename__ = 'users_groups' + __tablename__ = "users_groups" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) users_group_id = Column("users_group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) users_group_name = Column("users_group_name", String(255), nullable=False, unique=True, default=None) user_group_description = Column("user_group_description", String(10000), nullable=True, unique=None, default=None) users_group_active = Column("users_group_active", Boolean(), nullable=True, unique=None, default=None) - inherit_default_permissions = Column("users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + inherit_default_permissions = Column( + "users_group_inherit_default_permissions", Boolean(), nullable=False, unique=None, default=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) _group_data = Column("group_data", LargeBinary(), nullable=True) # JSON data - members = relationship('UserGroupMember', cascade="all, delete, delete-orphan", lazy="joined") - users_group_to_perm = relationship('UserGroupToPerm', cascade='all') - users_group_repo_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - users_group_repo_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - user_user_group_to_perm = relationship('UserUserGroupToPerm', cascade='all') - user_group_user_group_to_perm = relationship('UserGroupUserGroupToPerm', primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", cascade='all') + members = relationship("UserGroupMember", cascade="all, delete, delete-orphan", lazy="joined") + users_group_to_perm = relationship("UserGroupToPerm", cascade="all") + users_group_repo_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + users_group_repo_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + user_user_group_to_perm = relationship("UserUserGroupToPerm", cascade="all") + user_group_user_group_to_perm = relationship( + "UserGroupUserGroupToPerm", + primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id", + cascade="all", + ) - user = relationship('User', primaryjoin="User.user_id==UserGroup.user_id") + user = relationship("User", primaryjoin="User.user_id==UserGroup.user_id") @classmethod def _load_group_data(cls, column): @@ -1258,6 +1242,7 @@ class UserGroup(Base, BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property @@ -1276,37 +1261,33 @@ class UserGroup(Base, BaseModel): log.error(traceback.format_exc()) def __unicode__(self): - return u"<%s('id:%s:%s')>" % (self.__class__.__name__, - self.users_group_id, - self.users_group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.users_group_id, self.users_group_name) @classmethod - def get_by_group_name(cls, group_name, cache=False, - case_insensitive=False): + def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - q = cls.query().filter(func.lower(cls.users_group_name) == - func.lower(group_name)) + q = cls.query().filter(func.lower(cls.users_group_name) == func.lower(group_name)) else: q = cls.query().filter(cls.users_group_name == group_name) if cache: - q = q.options( - FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) + q = q.options(FromCache("sql_cache_short", "get_group_%s" % _hash_key(group_name))) return q.scalar() @classmethod def get(cls, user_group_id, cache=False): user_group = cls.query() if cache: - user_group = user_group.options( - FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) + user_group = user_group.options(FromCache("sql_cache_short", "get_users_group_%s" % user_group_id)) return user_group.get(user_group_id) def permissions(self, with_admins=True, with_owner=True): q = UserUserGroupToPerm.query().filter(UserUserGroupToPerm.user_group == self) - q = q.options(joinedload(UserUserGroupToPerm.user_group), - joinedload(UserUserGroupToPerm.user), - joinedload(UserUserGroupToPerm.permission),) + q = q.options( + joinedload(UserUserGroupToPerm.user_group), + joinedload(UserUserGroupToPerm.user), + joinedload(UserUserGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1324,7 +1305,7 @@ class UserGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'usergroup.admin' + _admin_perm = "usergroup.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1348,9 +1329,11 @@ class UserGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupUserGroupToPerm.query().filter(UserGroupUserGroupToPerm.target_user_group == self) - q = q.options(joinedload(UserGroupUserGroupToPerm.user_group), - joinedload(UserGroupUserGroupToPerm.target_user_group), - joinedload(UserGroupUserGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupUserGroupToPerm.user_group), + joinedload(UserGroupUserGroupToPerm.target_user_group), + joinedload(UserGroupUserGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1360,11 +1343,12 @@ class UserGroup(Base, BaseModel): return perm_rows - def _get_default_perms(self, user_group, suffix=''): + def _get_default_perms(self, user_group, suffix=""): from rhodecode.model.permission import PermissionModel + return PermissionModel().get_default_perms(user_group.users_group_to_perm, suffix) - def get_default_perms(self, suffix=''): + def get_default_perms(self, suffix=""): return self._get_default_perms(self, suffix) def get_api_data(self, with_group_members=True, include_secrets=False): @@ -1375,12 +1359,12 @@ class UserGroup(Base, BaseModel): """ user_group = self data = { - 'users_group_id': user_group.users_group_id, - 'group_name': user_group.users_group_name, - 'group_description': user_group.user_group_description, - 'active': user_group.users_group_active, - 'owner': user_group.user.username, - 'owner_email': user_group.user.email, + "users_group_id": user_group.users_group_id, + "group_name": user_group.users_group_name, + "group_description": user_group.user_group_description, + "active": user_group.users_group_active, + "owner": user_group.user.username, + "owner_email": user_group.user.email, } if with_group_members: @@ -1388,199 +1372,179 @@ class UserGroup(Base, BaseModel): for user in user_group.members: user = user.user users.append(user.get_api_data(include_secrets=include_secrets)) - data['users'] = users + data["users"] = users return data class UserGroupMember(Base, BaseModel): - __tablename__ = 'users_groups_members' + __tablename__ = "users_groups_members" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_member_id = Column("users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) + users_group_member_id = Column( + "users_group_member_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) - user = relationship('User', lazy='joined') - users_group = relationship('UserGroup') + user = relationship("User", lazy="joined") + users_group = relationship("UserGroup") - def __init__(self, gr_id='', u_id=''): + def __init__(self, gr_id="", u_id=""): self.users_group_id = gr_id self.user_id = u_id class RepositoryField(Base, BaseModel): - __tablename__ = 'repositories_fields' + __tablename__ = "repositories_fields" __table_args__ = ( - UniqueConstraint('repository_id', 'field_key'), # no-multi field - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("repository_id", "field_key"), # no-multi field + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - PREFIX = 'ex_' # prefix used in form to not conflict with already existing fields + PREFIX = "ex_" # prefix used in form to not conflict with already existing fields repo_field_id = Column("repo_field_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) field_key = Column("field_key", String(250)) field_label = Column("field_label", String(1024), nullable=False) field_value = Column("field_value", String(10000), nullable=False) field_desc = Column("field_desc", String(1024), nullable=False) field_type = Column("field_type", String(255), nullable=False, unique=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - repository = relationship('Repository') + repository = relationship("Repository") @property def field_key_prefixed(self): - return 'ex_%s' % self.field_key + return "ex_%s" % self.field_key @classmethod def un_prefix_key(cls, key): if key.startswith(cls.PREFIX): - return key[len(cls.PREFIX):] + return key[len(cls.PREFIX) :] return key @classmethod def get_by_key_name(cls, key, repo): - row = cls.query()\ - .filter(cls.repository == repo)\ - .filter(cls.field_key == key).scalar() + row = cls.query().filter(cls.repository == repo).filter(cls.field_key == key).scalar() return row class Repository(Base, BaseModel): - __tablename__ = 'repositories' + __tablename__ = "repositories" __table_args__ = ( - Index('r_repo_name_idx', 'repo_name', mysql_length=255), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("r_repo_name_idx", "repo_name", mysql_length=255), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - DEFAULT_CLONE_URI = '{scheme}://{user}@{netloc}/{repo}' - DEFAULT_CLONE_URI_ID = '{scheme}://{user}@{netloc}/_{repoid}' + DEFAULT_CLONE_URI = "{scheme}://{user}@{netloc}/{repo}" + DEFAULT_CLONE_URI_ID = "{scheme}://{user}@{netloc}/_{repoid}" - STATE_CREATED = 'repo_state_created' - STATE_PENDING = 'repo_state_pending' - STATE_ERROR = 'repo_state_error' + STATE_CREATED = "repo_state_created" + STATE_PENDING = "repo_state_pending" + STATE_ERROR = "repo_state_error" - LOCK_AUTOMATIC = 'lock_auto' - LOCK_API = 'lock_api' - LOCK_WEB = 'lock_web' - LOCK_PULL = 'lock_pull' + LOCK_AUTOMATIC = "lock_auto" + LOCK_API = "lock_api" + LOCK_WEB = "lock_web" + LOCK_PULL = "lock_pull" NAME_SEP = URL_SEP - repo_id = Column( - "repo_id", Integer(), nullable=False, unique=True, default=None, - primary_key=True) - _repo_name = Column( - "repo_name", Text(), nullable=False, default=None) - _repo_name_hash = Column( - "repo_name_hash", String(255), nullable=False, unique=True) + repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + _repo_name = Column("repo_name", Text(), nullable=False, default=None) + _repo_name_hash = Column("repo_name_hash", String(255), nullable=False, unique=True) repo_state = Column("repo_state", String(255), nullable=True) - clone_uri = Column( - "clone_uri", EncryptedTextValue(), nullable=True, unique=False, - default=None) - repo_type = Column( - "repo_type", String(255), nullable=False, unique=False, default=None) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=False, default=None) - private = Column( - "private", Boolean(), nullable=True, unique=None, default=None) - enable_statistics = Column( - "statistics", Boolean(), nullable=True, unique=None, default=True) - enable_downloads = Column( - "downloads", Boolean(), nullable=True, unique=None, default=True) - description = Column( - "description", String(10000), nullable=True, unique=None, default=None) + clone_uri = Column("clone_uri", EncryptedTextValue(), nullable=True, unique=False, default=None) + repo_type = Column("repo_type", String(255), nullable=False, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + private = Column("private", Boolean(), nullable=True, unique=None, default=None) + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) + enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) + description = Column("description", String(10000), nullable=True, unique=None, default=None) created_on = Column( - 'created_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) - _landing_revision = Column( - "landing_revision", String(255), nullable=False, unique=False, - default=None) - enable_locking = Column( - "enable_locking", Boolean(), nullable=False, unique=None, - default=False) - _locked = Column( - "locked", String(255), nullable=True, unique=False, default=None) - _changeset_cache = Column( - "changeset_cache", LargeBinary(), nullable=True) # JSON data + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + _landing_revision = Column("landing_revision", String(255), nullable=False, unique=False, default=None) + enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) + _changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # JSON data fork_id = Column( - "fork_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=False, default=None) - group_id = Column( - "group_id", Integer(), ForeignKey('groups.group_id'), nullable=True, - unique=False, default=None) + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) - user = relationship('User', lazy='joined') - fork = relationship('Repository', remote_side=repo_id, lazy='joined') - group = relationship('RepoGroup', lazy='joined') - repo_to_perm = relationship( - 'UserRepoToPerm', cascade='all', - order_by='UserRepoToPerm.repo_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoToPerm', cascade='all') - stats = relationship('Statistics', cascade='all', uselist=False) + user = relationship("User", lazy="joined") + fork = relationship("Repository", remote_side=repo_id, lazy="joined") + group = relationship("RepoGroup", lazy="joined") + repo_to_perm = relationship("UserRepoToPerm", cascade="all", order_by="UserRepoToPerm.repo_to_perm_id") + users_group_to_perm = relationship("UserGroupRepoToPerm", cascade="all") + stats = relationship("Statistics", cascade="all", uselist=False) followers = relationship( - 'UserFollowing', - primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', - cascade='all') - extra_fields = relationship( - 'RepositoryField', cascade="all, delete, delete-orphan") - logs = relationship('UserLog') - comments = relationship( - 'ChangesetComment', cascade="all, delete, delete-orphan") + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) + extra_fields = relationship("RepositoryField", cascade="all, delete, delete-orphan") + logs = relationship("UserLog") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") pull_requests_source = relationship( - 'PullRequest', - primaryjoin='PullRequest.source_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.source_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) pull_requests_target = relationship( - 'PullRequest', - primaryjoin='PullRequest.target_repo_id==Repository.repo_id', - cascade="all, delete, delete-orphan") - ui = relationship('RepoRhodeCodeUi', cascade="all") - settings = relationship('RepoRhodeCodeSetting', cascade="all") - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + "PullRequest", + primaryjoin="PullRequest.target_repo_id==Repository.repo_id", + cascade="all, delete, delete-orphan", + ) + ui = relationship("RepoRhodeCodeUi", cascade="all") + settings = relationship("RepoRhodeCodeSetting", cascade="all") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") def __unicode__(self): - return u"<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, - safe_str(self.repo_name)) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.repo_id, safe_str(self.repo_name)) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def landing_rev(self): # always should return [rev_type, rev] if self._landing_revision: - _rev_info = self._landing_revision.split(':') + _rev_info = self._landing_revision.split(":") if len(_rev_info) < 2: - _rev_info.insert(0, 'rev') + _rev_info.insert(0, "rev") return [_rev_info[0], _rev_info[1]] return [None, None] @landing_rev.setter def landing_rev(self, val): - if ':' not in val: - raise ValueError('value must be delimited with `:` and consist ' - 'of :, got %s instead' % val) + if ":" not in val: + raise ValueError("value must be delimited with `:` and consist of :, got %s instead" % val) self._landing_revision = val @hybrid_property def locked(self): if self._locked: - user_id, timelocked, reason = self._locked.split(':') + user_id, timelocked, reason = self._locked.split(":") lock_values = int(user_id), timelocked, reason else: lock_values = [None, None, None] @@ -1589,13 +1553,14 @@ class Repository(Base, BaseModel): @locked.setter def locked(self, val): if val and isinstance(val, (list, tuple)): - self._locked = ':'.join(map(str, val)) + self._locked = ":".join(map(str, val)) else: self._locked = None @hybrid_property def changeset_cache(self): from rhodecode.lib.vcs.backends.base import EmptyCommit + dummy = EmptyCommit().__json__() if not self._changeset_cache: return dummy @@ -1641,13 +1606,12 @@ class Repository(Base, BaseModel): if cache: if identity_cache: - val = cls.identity_cache(session, 'repo_name', repo_name) + val = cls.identity_cache(session, "repo_name", repo_name) if val: return val else: cache_key = "get_repo_by_name_%s" % _hash_key(repo_name) - q = q.options( - FromCache("sql_cache_short", cache_key)) + q = q.options(FromCache("sql_cache_short", cache_key)) return q.scalar() @@ -1668,8 +1632,7 @@ class Repository(Base, BaseModel): :param cls: """ - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == cls.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == cls.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1686,8 +1649,7 @@ class Repository(Base, BaseModel): return is_valid_repo(repo_name, cls.base_path()) @classmethod - def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repos(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = Repository.query() if not isinstance(user_id, Optional): @@ -1729,7 +1691,7 @@ class Repository(Base, BaseModel): cur_gr = self.group groups.insert(0, cur_gr) while 1: - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break @@ -1747,8 +1709,7 @@ class Repository(Base, BaseModel): Returns base full path for that repository means where it actually exists on a filesystem """ - q = Session().query(RhodeCodeUi).filter( - RhodeCodeUi.ui_key == self.NAME_SEP) + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == self.NAME_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return q.one().ui_value @@ -1766,10 +1727,7 @@ class Repository(Base, BaseModel): """ Returns associated cache keys for that repo """ - return CacheKey.query()\ - .filter(CacheKey.cache_args == self.repo_name)\ - .order_by(CacheKey.cache_key)\ - .all() + return CacheKey.query().filter(CacheKey.cache_args == self.repo_name).order_by(CacheKey.cache_key).all() def get_new_name(self, repo_name): """ @@ -1786,13 +1744,16 @@ class Repository(Base, BaseModel): Returns db based config object. """ from rhodecode.lib.utils import make_db_config + return make_db_config(clear_session=False, repo=self) def permissions(self, with_admins=True, with_owner=True): q = UserRepoToPerm.query().filter(UserRepoToPerm.repository == self) - q = q.options(joinedload(UserRepoToPerm.repository), - joinedload(UserRepoToPerm.user), - joinedload(UserRepoToPerm.permission),) + q = q.options( + joinedload(UserRepoToPerm.repository), + joinedload(UserRepoToPerm.user), + joinedload(UserRepoToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -1810,7 +1771,7 @@ class Repository(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'repository.admin' + _admin_perm = "repository.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -1833,11 +1794,12 @@ class Repository(Base, BaseModel): return super_admin_rows + owner_row + perm_rows def permission_user_groups(self): - q = UserGroupRepoToPerm.query().filter( - UserGroupRepoToPerm.repository == self) - q = q.options(joinedload(UserGroupRepoToPerm.repository), - joinedload(UserGroupRepoToPerm.users_group), - joinedload(UserGroupRepoToPerm.permission),) + q = UserGroupRepoToPerm.query().filter(UserGroupRepoToPerm.repository == self) + q = q.options( + joinedload(UserGroupRepoToPerm.repository), + joinedload(UserGroupRepoToPerm.users_group), + joinedload(UserGroupRepoToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -1863,32 +1825,30 @@ class Repository(Base, BaseModel): _user_id, _time, _reason = self.locked data = { - 'repo_id': repo.repo_id, - 'repo_name': repo.repo_name, - 'repo_type': repo.repo_type, - 'clone_uri': repo.clone_uri or '', - 'url': RepoModel().get_url(self), - 'private': repo.private, - 'created_on': repo.created_on, - 'description': repo.description_safe, - 'landing_rev': repo.landing_rev, - 'owner': repo.user.username, - 'fork_of': repo.fork.repo_name if repo.fork else None, - 'fork_of_id': repo.fork.repo_id if repo.fork else None, - 'enable_statistics': repo.enable_statistics, - 'enable_locking': repo.enable_locking, - 'enable_downloads': repo.enable_downloads, - 'last_changeset': repo.changeset_cache, - 'locked_by': User.get(_user_id).get_api_data( - include_secrets=include_secrets) if _user_id else None, - 'locked_date': time_to_datetime(_time) if _time else None, - 'lock_reason': _reason if _reason else None, + "repo_id": repo.repo_id, + "repo_name": repo.repo_name, + "repo_type": repo.repo_type, + "clone_uri": repo.clone_uri or "", + "url": RepoModel().get_url(self), + "private": repo.private, + "created_on": repo.created_on, + "description": repo.description_safe, + "landing_rev": repo.landing_rev, + "owner": repo.user.username, + "fork_of": repo.fork.repo_name if repo.fork else None, + "fork_of_id": repo.fork.repo_id if repo.fork else None, + "enable_statistics": repo.enable_statistics, + "enable_locking": repo.enable_locking, + "enable_downloads": repo.enable_downloads, + "last_changeset": repo.changeset_cache, + "locked_by": User.get(_user_id).get_api_data(include_secrets=include_secrets) if _user_id else None, + "locked_date": time_to_datetime(_time) if _time else None, + "lock_reason": _reason if _reason else None, } # TODO: mikhail: should be per-repo settings here rc_config = SettingsModel().get_all_settings() - repository_fields = str2bool( - rc_config.get('rhodecode_repository_fields')) + repository_fields = str2bool(rc_config.get("rhodecode_repository_fields")) if repository_fields: for f in self.extra_fields: data[f.field_key_prefixed] = f.field_value @@ -1936,7 +1896,7 @@ class Repository(Base, BaseModel): # TODO: johbo: This is part of the business logic and should be moved # into the RepositoryModel. - if action not in ('push', 'pull'): + if action not in ("push", "pull"): raise ValueError("Invalid action value: %s" % repr(action)) # defines if locked error should be thrown to user @@ -1949,40 +1909,38 @@ class Repository(Base, BaseModel): lock_info = repo.locked if repo and (repo.enable_locking or not only_when_enabled): - if action == 'push': + if action == "push": # check if it's already locked !, if it is compare users locked_by_user_id = lock_info[0] if user.user_id == locked_by_user_id: - log.debug( - 'Got `push` action from user %s, now unlocking', user) + log.debug("Got `push` action from user %s, now unlocking", user) # unlock if we have push from user who locked make_lock = False else: # we're not the same user who locked, ban with # code defined in settings (default is 423 HTTP Locked) ! - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True - elif action == 'pull': + elif action == "pull": # [0] user [1] date if lock_info[0] and lock_info[1]: - log.debug('Repo %s is currently locked by %s', repo, user) + log.debug("Repo %s is currently locked by %s", repo, user) currently_locked = True else: - log.debug('Setting lock on repo %s by %s', repo, user) + log.debug("Setting lock on repo %s by %s", repo, user) make_lock = True else: - log.debug('Repository %s do not have locking enabled', repo) + log.debug("Repository %s do not have locking enabled", repo) - log.debug('FINAL locking values make_lock:%s,locked:%s,locked_by:%s', - make_lock, currently_locked, lock_info) + log.debug("FINAL locking values make_lock:%s,locked:%s,locked_by:%s", make_lock, currently_locked, lock_info) from rhodecode.lib.auth import HasRepoPermissionAny - perm_check = HasRepoPermissionAny('repository.write', 'repository.admin') + + perm_check = HasRepoPermissionAny("repository.write", "repository.admin") if make_lock and not perm_check(repo_name=repo.repo_name, user=user): # if we don't have at least write permission we cannot make a lock - log.debug('lock state reset back to FALSE due to lack ' - 'of at least read permission') + log.debug("lock state reset back to FALSE due to lack of at least read permission") make_lock = False return make_lock, currently_locked, lock_info @@ -1996,45 +1954,44 @@ class Repository(Base, BaseModel): clone_uri = self.clone_uri if clone_uri: import urlobject + url_obj = urlobject.URLObject(cleaned_uri(clone_uri)) if url_obj.password: - clone_uri = url_obj.with_password('*****') + clone_uri = url_obj.with_password("*****") return clone_uri def clone_url(self, **override): from rhodecode.model.settings import SettingsModel uri_tmpl = None - if 'with_id' in override: + if "with_id" in override: uri_tmpl = self.DEFAULT_CLONE_URI_ID - del override['with_id'] + del override["with_id"] - if 'uri_tmpl' in override: - uri_tmpl = override['uri_tmpl'] - del override['uri_tmpl'] + if "uri_tmpl" in override: + uri_tmpl = override["uri_tmpl"] + del override["uri_tmpl"] # we didn't override our tmpl from **overrides if not uri_tmpl: rc_config = SettingsModel().get_all_settings(cache=True) - uri_tmpl = rc_config.get( - 'rhodecode_clone_uri_tmpl') or self.DEFAULT_CLONE_URI + uri_tmpl = rc_config.get("rhodecode_clone_uri_tmpl") or self.DEFAULT_CLONE_URI request = get_current_request() - return get_clone_url(request=request, - uri_tmpl=uri_tmpl, - repo_name=self.repo_name, - repo_id=self.repo_id, **override) + return get_clone_url( + request=request, uri_tmpl=uri_tmpl, repo_name=self.repo_name, repo_id=self.repo_id, **override + ) def set_state(self, state): self.repo_state = state Session().add(self) - #========================================================================== + + # ========================================================================== # SCM PROPERTIES - #========================================================================== + # ========================================================================== def get_commit(self, commit_id=None, commit_idx=None, pre_load=None): - return get_commit_safe( - self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) + return get_commit_safe(self.scm_instance(), commit_id, commit_idx, pre_load=pre_load) def get_changeset(self, rev=None, pre_load=None): warnings.warn("Use get_commit", DeprecationWarning) @@ -2044,8 +2001,7 @@ class Repository(Base, BaseModel): commit_id = rev else: commit_idx = rev - return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, - pre_load=pre_load) + return self.get_commit(commit_id=commit_id, commit_idx=commit_idx, pre_load=pre_load) def get_landing_commit(self): """ @@ -2072,12 +2028,12 @@ class Repository(Base, BaseModel): :param cs_cache: """ from rhodecode.lib.vcs.backends.base import BaseChangeset + if cs_cache is None: # use no-cache version here scm_repo = self.scm_instance(cache=False, config=config) if scm_repo: - cs_cache = scm_repo.get_commit( - pre_load=["author", "date", "message", "parents"]) + cs_cache = scm_repo.get_commit(pre_load=["author", "date", "message", "parents"]) else: cs_cache = EmptyCommit() @@ -2085,28 +2041,28 @@ class Repository(Base, BaseModel): cs_cache = cs_cache.__json__() def is_outdated(new_cs_cache): - if (new_cs_cache['raw_id'] != self.changeset_cache['raw_id'] or - new_cs_cache['revision'] != self.changeset_cache['revision']): + if ( + new_cs_cache["raw_id"] != self.changeset_cache["raw_id"] + or new_cs_cache["revision"] != self.changeset_cache["revision"] + ): return True return False # check if we have maybe already latest cached revision if is_outdated(cs_cache) or not self.changeset_cache: _default = datetime.datetime.fromtimestamp(0) - last_change = cs_cache.get('date') or _default - log.debug('updated repo %s with new commit cache %s', - self.repo_name, cs_cache) + last_change = cs_cache.get("date") or _default + log.debug("updated repo %s with new commit cache %s", self.repo_name, cs_cache) self.updated_on = last_change self.changeset_cache = cs_cache Session().add(self) Session().commit() else: - log.debug('Skipping update_commit_cache for repo:`%s` ' - 'commit already with latest changes', self.repo_name) + log.debug("Skipping update_commit_cache for repo:`%s` commit already with latest changes", self.repo_name) @property def tip(self): - return self.get_commit('tip') + return self.get_commit("tip") @property def author(self): @@ -2122,8 +2078,7 @@ class Repository(Base, BaseModel): :param revisions: filter query by revisions only """ - cmts = ChangesetComment.query()\ - .filter(ChangesetComment.repo == self) + cmts = ChangesetComment.query().filter(ChangesetComment.repo == self) if revisions: cmts = cmts.filter(ChangesetComment.revision.in_(revisions)) grouped = collections.defaultdict(list) @@ -2137,19 +2092,14 @@ class Repository(Base, BaseModel): :param revisions: list of revisions to get statuses for """ - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.repo == self)\ - .filter(ChangesetStatus.version == 0) + statuses = ChangesetStatus.query().filter(ChangesetStatus.repo == self).filter(ChangesetStatus.version == 0) if revisions: # Try doing the filtering in chunks to avoid hitting limits size = 500 status_results = [] for chunk in range(0, len(revisions), size): - status_results += statuses.filter( - ChangesetStatus.revision.in_( - revisions[chunk: chunk+size]) - ).all() + status_results += statuses.filter(ChangesetStatus.revision.in_(revisions[chunk : chunk + size])).all() else: status_results = statuses.all() @@ -2169,8 +2119,7 @@ class Repository(Base, BaseModel): if stat.pull_request: pr_id = stat.pull_request.pull_request_id pr_repo = stat.pull_request.target_repo.repo_name - grouped[stat.revision] = [str(stat.status), stat.status_lbl, - pr_id, pr_repo] + grouped[stat.revision] = [str(stat.status), stat.status_lbl, pr_id, pr_repo] return grouped # ========================================================================== @@ -2182,9 +2131,9 @@ class Repository(Base, BaseModel): # Passing a config will not hit the cache currently only used # for repo2dbmapper - config = kwargs.pop('config', None) - cache = kwargs.pop('cache', None) - full_cache = str2bool(rhodecode.CONFIG.get('vcs_full_cache')) + config = kwargs.pop("config", None) + cache = kwargs.pop("cache", None) + full_cache = str2bool(rhodecode.CONFIG.get("vcs_full_cache")) # if cache is NOT defined use default global, else we have a full # control over cache behaviour if cache is None and full_cache and not config: @@ -2197,73 +2146,78 @@ class Repository(Base, BaseModel): def _get_instance(self, cache=True, config=None): config = config or self._config custom_wire = { - 'cache': cache # controls the vcs.remote cache + "cache": cache # controls the vcs.remote cache } repo = get_vcs_instance( repo_path=safe_str(self.repo_full_path), config=config, with_wire=custom_wire, create=False, - _vcs_alias=self.repo_type) + _vcs_alias=self.repo_type, + ) return repo def __json__(self): - return {'landing_rev': self.landing_rev} + return {"landing_rev": self.landing_rev} def get_dict(self): - # Since we transformed `repo_name` to a hybrid property, we need to # keep compatibility with the code which uses `repo_name` field. result = super(Repository, self).get_dict() - result['repo_name'] = result.pop('_repo_name', None) + result["repo_name"] = result.pop("_repo_name", None) return result class RepoGroup(Base, BaseModel): - __tablename__ = 'groups' + __tablename__ = "groups" __table_args__ = ( - UniqueConstraint('group_name', 'group_parent_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("group_name", "group_parent_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CHOICES_SEPARATOR = '/' # used to generate select2 choices for nested groups + CHOICES_SEPARATOR = "/" # used to generate select2 choices for nested groups group_id = Column("group_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) group_name = Column("group_name", String(255), nullable=False, unique=True, default=None) - group_parent_id = Column("group_parent_id", Integer(), ForeignKey('groups.group_id'), nullable=True, unique=None, default=None) + group_parent_id = Column( + "group_parent_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) group_description = Column("group_description", String(10000), nullable=True, unique=None, default=None) enable_locking = Column("enable_locking", Boolean(), nullable=False, unique=None, default=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=False, default=None) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - updated_on = Column('updated_on', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) - personal = Column('personal', Boolean(), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column( + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) + personal = Column("personal", Boolean(), nullable=True, unique=None, default=None) - repo_group_to_perm = relationship('UserRepoGroupToPerm', cascade='all', order_by='UserRepoGroupToPerm.group_to_perm_id') - users_group_to_perm = relationship('UserGroupRepoGroupToPerm', cascade='all') - parent_group = relationship('RepoGroup', remote_side=group_id) - user = relationship('User') - integrations = relationship('Integration', - cascade="all, delete, delete-orphan") + repo_group_to_perm = relationship( + "UserRepoGroupToPerm", cascade="all", order_by="UserRepoGroupToPerm.group_to_perm_id" + ) + users_group_to_perm = relationship("UserGroupRepoGroupToPerm", cascade="all") + parent_group = relationship("RepoGroup", remote_side=group_id) + user = relationship("User") + integrations = relationship("Integration", cascade="all, delete, delete-orphan") - def __init__(self, group_name='', parent_group=None): + def __init__(self, group_name="", parent_group=None): self.group_name = group_name self.parent_group = parent_group def __unicode__(self): - return u"<%s('id:%s:%s')>" % ( - self.__class__.__name__, self.group_id, self.group_name) + return "<%s('id:%s:%s')>" % (self.__class__.__name__, self.group_id, self.group_name) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.group_description) @classmethod def _generate_choice(cls, repo_group): from webhelpers2.html import literal as _literal + _name = lambda k: _literal(cls.CHOICES_SEPARATOR.join(k)) return repo_group.group_id, _name(repo_group.full_path_splitted) @@ -2274,12 +2228,11 @@ class RepoGroup(Base, BaseModel): repo_groups = [] if show_empty_group: - repo_groups = [(-1, u'-- %s --' % _('No parent'))] + repo_groups = [(-1, "-- %s --" % _("No parent"))] repo_groups.extend([cls._generate_choice(x) for x in groups]) - repo_groups = sorted( - repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) + repo_groups = sorted(repo_groups, key=lambda t: t[1].split(cls.CHOICES_SEPARATOR)[0]) return repo_groups @classmethod @@ -2289,14 +2242,12 @@ class RepoGroup(Base, BaseModel): @classmethod def get_by_group_name(cls, group_name, cache=False, case_insensitive=False): if case_insensitive: - gr = cls.query().filter(func.lower(cls.group_name) - == func.lower(group_name)) + gr = cls.query().filter(func.lower(cls.group_name) == func.lower(group_name)) else: gr = cls.query().filter(cls.group_name == group_name) if cache: name_key = _hash_key(group_name) - gr = gr.options( - FromCache("sql_cache_short", "get_group_%s" % name_key)) + gr = gr.options(FromCache("sql_cache_short", "get_group_%s" % name_key)) return gr.scalar() @classmethod @@ -2305,13 +2256,10 @@ class RepoGroup(Base, BaseModel): if user.username == User.DEFAULT_USER: return None - return cls.query()\ - .filter(cls.personal == true()) \ - .filter(cls.user == user).scalar() + return cls.query().filter(cls.personal == true()).filter(cls.user == user).scalar() @classmethod - def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), - case_insensitive=True): + def get_all_repo_groups(cls, user_id=Optional(None), group_id=Optional(None), case_insensitive=True): q = RepoGroup.query() if not isinstance(user_id, Optional): @@ -2337,14 +2285,17 @@ class RepoGroup(Base, BaseModel): cnt = 0 while 1: cnt += 1 - gr = getattr(cur_gr, 'parent_group', None) + gr = getattr(cur_gr, "parent_group", None) cur_gr = cur_gr.parent_group if gr is None: break if cnt == parents_recursion_limit: # this will prevent accidental infinit loops - log.error('more than %s parents found for group %s, stopping ' - 'recursive parent fetching', parents_recursion_limit, self) + log.error( + "more than %s parents found for group %s, stopping recursive parent fetching", + parents_recursion_limit, + self, + ) break groups.insert(0, gr) @@ -2372,9 +2323,7 @@ class RepoGroup(Base, BaseModel): @property def repositories(self): - return Repository.query()\ - .filter(Repository.group == self)\ - .order_by(Repository.repo_name) + return Repository.query().filter(Repository.group == self).order_by(Repository.repo_name) @property def repositories_recursive_count(self): @@ -2423,15 +2372,16 @@ class RepoGroup(Base, BaseModel): :param group_name: """ - path_prefix = (self.parent_group.full_path_splitted if - self.parent_group else []) + path_prefix = self.parent_group.full_path_splitted if self.parent_group else [] return RepoGroup.url_sep().join(path_prefix + [group_name]) def permissions(self, with_admins=True, with_owner=True): q = UserRepoGroupToPerm.query().filter(UserRepoGroupToPerm.group == self) - q = q.options(joinedload(UserRepoGroupToPerm.group), - joinedload(UserRepoGroupToPerm.user), - joinedload(UserRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserRepoGroupToPerm.group), + joinedload(UserRepoGroupToPerm.user), + joinedload(UserRepoGroupToPerm.permission), + ) # get owners and admins and permissions. We do a trick of re-writing # objects from sqlalchemy to named-tuples due to sqlalchemy session @@ -2449,7 +2399,7 @@ class RepoGroup(Base, BaseModel): # each group perm_rows = sorted(perm_rows, key=display_sort) - _admin_perm = 'group.admin' + _admin_perm = "group.admin" owner_row = [] if with_owner: usr = AttributeDict(self.user.get_dict()) @@ -2473,9 +2423,11 @@ class RepoGroup(Base, BaseModel): def permission_user_groups(self): q = UserGroupRepoGroupToPerm.query().filter(UserGroupRepoGroupToPerm.group == self) - q = q.options(joinedload(UserGroupRepoGroupToPerm.group), - joinedload(UserGroupRepoGroupToPerm.users_group), - joinedload(UserGroupRepoGroupToPerm.permission),) + q = q.options( + joinedload(UserGroupRepoGroupToPerm.group), + joinedload(UserGroupRepoGroupToPerm.users_group), + joinedload(UserGroupRepoGroupToPerm.permission), + ) perm_rows = [] for _user_group in q.all(): @@ -2492,115 +2444,104 @@ class RepoGroup(Base, BaseModel): """ group = self data = { - 'group_id': group.group_id, - 'group_name': group.group_name, - 'group_description': group.description_safe, - 'parent_group': group.parent_group.group_name if group.parent_group else None, - 'repositories': [x.repo_name for x in group.repositories], - 'owner': group.user.username, + "group_id": group.group_id, + "group_name": group.group_name, + "group_description": group.description_safe, + "parent_group": group.parent_group.group_name if group.parent_group else None, + "repositories": [x.repo_name for x in group.repositories], + "owner": group.user.username, } return data class Permission(Base, BaseModel): - __tablename__ = 'permissions' + __tablename__ = "permissions" __table_args__ = ( - Index('p_perm_name_idx', 'permission_name'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("p_perm_name_idx", "permission_name"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) PERMS = [ - ('hg.admin', _('RhodeCode Super Administrator')), - - ('repository.none', _('Repository no access')), - ('repository.read', _('Repository read access')), - ('repository.write', _('Repository write access')), - ('repository.admin', _('Repository admin access')), - - ('group.none', _('Repository group no access')), - ('group.read', _('Repository group read access')), - ('group.write', _('Repository group write access')), - ('group.admin', _('Repository group admin access')), - - ('usergroup.none', _('User group no access')), - ('usergroup.read', _('User group read access')), - ('usergroup.write', _('User group write access')), - ('usergroup.admin', _('User group admin access')), - - ('hg.repogroup.create.false', _('Repository Group creation disabled')), - ('hg.repogroup.create.true', _('Repository Group creation enabled')), - - ('hg.usergroup.create.false', _('User Group creation disabled')), - ('hg.usergroup.create.true', _('User Group creation enabled')), - - ('hg.create.none', _('Repository creation disabled')), - ('hg.create.repository', _('Repository creation enabled')), - ('hg.create.write_on_repogroup.true', _('Repository creation enabled with write permission to a repository group')), - ('hg.create.write_on_repogroup.false', _('Repository creation disabled with write permission to a repository group')), - - ('hg.fork.none', _('Repository forking disabled')), - ('hg.fork.repository', _('Repository forking enabled')), - - ('hg.register.none', _('Registration disabled')), - ('hg.register.manual_activate', _('User Registration with manual account activation')), - ('hg.register.auto_activate', _('User Registration with automatic account activation')), - - ('hg.password_reset.enabled', _('Password reset enabled')), - ('hg.password_reset.hidden', _('Password reset hidden')), - ('hg.password_reset.disabled', _('Password reset disabled')), - - ('hg.extern_activate.manual', _('Manual activation of external account')), - ('hg.extern_activate.auto', _('Automatic activation of external account')), - - ('hg.inherit_default_perms.false', _('Inherit object permissions from default user disabled')), - ('hg.inherit_default_perms.true', _('Inherit object permissions from default user enabled')), + ("hg.admin", _("RhodeCode Super Administrator")), + ("repository.none", _("Repository no access")), + ("repository.read", _("Repository read access")), + ("repository.write", _("Repository write access")), + ("repository.admin", _("Repository admin access")), + ("group.none", _("Repository group no access")), + ("group.read", _("Repository group read access")), + ("group.write", _("Repository group write access")), + ("group.admin", _("Repository group admin access")), + ("usergroup.none", _("User group no access")), + ("usergroup.read", _("User group read access")), + ("usergroup.write", _("User group write access")), + ("usergroup.admin", _("User group admin access")), + ("hg.repogroup.create.false", _("Repository Group creation disabled")), + ("hg.repogroup.create.true", _("Repository Group creation enabled")), + ("hg.usergroup.create.false", _("User Group creation disabled")), + ("hg.usergroup.create.true", _("User Group creation enabled")), + ("hg.create.none", _("Repository creation disabled")), + ("hg.create.repository", _("Repository creation enabled")), + ( + "hg.create.write_on_repogroup.true", + _("Repository creation enabled with write permission to a repository group"), + ), + ( + "hg.create.write_on_repogroup.false", + _("Repository creation disabled with write permission to a repository group"), + ), + ("hg.fork.none", _("Repository forking disabled")), + ("hg.fork.repository", _("Repository forking enabled")), + ("hg.register.none", _("Registration disabled")), + ("hg.register.manual_activate", _("User Registration with manual account activation")), + ("hg.register.auto_activate", _("User Registration with automatic account activation")), + ("hg.password_reset.enabled", _("Password reset enabled")), + ("hg.password_reset.hidden", _("Password reset hidden")), + ("hg.password_reset.disabled", _("Password reset disabled")), + ("hg.extern_activate.manual", _("Manual activation of external account")), + ("hg.extern_activate.auto", _("Automatic activation of external account")), + ("hg.inherit_default_perms.false", _("Inherit object permissions from default user disabled")), + ("hg.inherit_default_perms.true", _("Inherit object permissions from default user enabled")), ] # definition of system default permissions for DEFAULT user DEFAULT_USER_PERMISSIONS = [ - 'repository.read', - 'group.read', - 'usergroup.read', - 'hg.create.repository', - 'hg.repogroup.create.false', - 'hg.usergroup.create.false', - 'hg.create.write_on_repogroup.true', - 'hg.fork.repository', - 'hg.register.manual_activate', - 'hg.password_reset.enabled', - 'hg.extern_activate.auto', - 'hg.inherit_default_perms.true', + "repository.read", + "group.read", + "usergroup.read", + "hg.create.repository", + "hg.repogroup.create.false", + "hg.usergroup.create.false", + "hg.create.write_on_repogroup.true", + "hg.fork.repository", + "hg.register.manual_activate", + "hg.password_reset.enabled", + "hg.extern_activate.auto", + "hg.inherit_default_perms.true", ] # defines which permissions are more important higher the more important # Weight defines which permissions are more important. # The higher number the more important. PERM_WEIGHTS = { - 'repository.none': 0, - 'repository.read': 1, - 'repository.write': 3, - 'repository.admin': 4, - - 'group.none': 0, - 'group.read': 1, - 'group.write': 3, - 'group.admin': 4, - - 'usergroup.none': 0, - 'usergroup.read': 1, - 'usergroup.write': 3, - 'usergroup.admin': 4, - - 'hg.repogroup.create.false': 0, - 'hg.repogroup.create.true': 1, - - 'hg.usergroup.create.false': 0, - 'hg.usergroup.create.true': 1, - - 'hg.fork.none': 0, - 'hg.fork.repository': 1, - 'hg.create.none': 0, - 'hg.create.repository': 1 + "repository.none": 0, + "repository.read": 1, + "repository.write": 3, + "repository.admin": 4, + "group.none": 0, + "group.read": 1, + "group.write": 3, + "group.admin": 4, + "usergroup.none": 0, + "usergroup.read": 1, + "usergroup.write": 3, + "usergroup.admin": 4, + "hg.repogroup.create.false": 0, + "hg.repogroup.create.true": 1, + "hg.usergroup.create.false": 0, + "hg.usergroup.create.true": 1, + "hg.fork.none": 0, + "hg.fork.repository": 1, + "hg.create.none": 0, + "hg.create.repository": 1, } permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) @@ -2608,9 +2549,7 @@ class Permission(Base, BaseModel): permission_longname = Column("permission_longname", String(255), nullable=True, unique=None, default=None) def __unicode__(self): - return u"<%s('%s:%s')>" % ( - self.__class__.__name__, self.permission_id, self.permission_name - ) + return "<%s('%s:%s')>" % (self.__class__.__name__, self.permission_id, self.permission_name) @classmethod def get_by_key(cls, key): @@ -2618,130 +2557,109 @@ class Permission(Base, BaseModel): @classmethod def get_default_repo_perms(cls, user_id, repo_id=None): - q = Session().query(UserRepoToPerm, Repository, Permission)\ - .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id))\ - .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id))\ + q = ( + Session() + .query(UserRepoToPerm, Repository, Permission) + .join((Permission, UserRepoToPerm.permission_id == Permission.permission_id)) + .join((Repository, UserRepoToPerm.repository_id == Repository.repo_id)) .filter(UserRepoToPerm.user_id == user_id) + ) if repo_id: q = q.filter(UserRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_repo_perms_from_user_group(cls, user_id, repo_id=None): - q = Session().query(UserGroupRepoToPerm, Repository, Permission)\ - .join( - Permission, - UserGroupRepoToPerm.permission_id == Permission.permission_id)\ - .join( - Repository, - UserGroupRepoToPerm.repository_id == Repository.repo_id)\ - .join( - UserGroup, - UserGroupRepoToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + q = ( + Session() + .query(UserGroupRepoToPerm, Repository, Permission) + .join(Permission, UserGroupRepoToPerm.permission_id == Permission.permission_id) + .join(Repository, UserGroupRepoToPerm.repository_id == Repository.repo_id) + .join(UserGroup, UserGroupRepoToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_id: q = q.filter(UserGroupRepoToPerm.repository_id == repo_id) return q.all() @classmethod def get_default_group_perms(cls, user_id, repo_group_id=None): - q = Session().query(UserRepoGroupToPerm, RepoGroup, Permission)\ - .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id))\ - .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id))\ + q = ( + Session() + .query(UserRepoGroupToPerm, RepoGroup, Permission) + .join((Permission, UserRepoGroupToPerm.permission_id == Permission.permission_id)) + .join((RepoGroup, UserRepoGroupToPerm.group_id == RepoGroup.group_id)) .filter(UserRepoGroupToPerm.user_id == user_id) + ) if repo_group_id: q = q.filter(UserRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod - def get_default_group_perms_from_user_group( - cls, user_id, repo_group_id=None): - q = Session().query(UserGroupRepoGroupToPerm, RepoGroup, Permission)\ - .join( - Permission, - UserGroupRepoGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - RepoGroup, - UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id)\ - .join( - UserGroup, - UserGroupRepoGroupToPerm.users_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupRepoGroupToPerm.users_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_group_perms_from_user_group(cls, user_id, repo_group_id=None): + q = ( + Session() + .query(UserGroupRepoGroupToPerm, RepoGroup, Permission) + .join(Permission, UserGroupRepoGroupToPerm.permission_id == Permission.permission_id) + .join(RepoGroup, UserGroupRepoGroupToPerm.group_id == RepoGroup.group_id) + .join(UserGroup, UserGroupRepoGroupToPerm.users_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupRepoGroupToPerm.users_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if repo_group_id: q = q.filter(UserGroupRepoGroupToPerm.group_id == repo_group_id) return q.all() @classmethod def get_default_user_group_perms(cls, user_id, user_group_id=None): - q = Session().query(UserUserGroupToPerm, UserGroup, Permission)\ - .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id))\ - .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id))\ + q = ( + Session() + .query(UserUserGroupToPerm, UserGroup, Permission) + .join((Permission, UserUserGroupToPerm.permission_id == Permission.permission_id)) + .join((UserGroup, UserUserGroupToPerm.user_group_id == UserGroup.users_group_id)) .filter(UserUserGroupToPerm.user_id == user_id) + ) if user_group_id: q = q.filter(UserUserGroupToPerm.user_group_id == user_group_id) return q.all() @classmethod - def get_default_user_group_perms_from_user_group( - cls, user_id, user_group_id=None): - TargetUserGroup = aliased(UserGroup, name='target_user_group') - q = Session().query(UserGroupUserGroupToPerm, UserGroup, Permission)\ - .join( - Permission, - UserGroupUserGroupToPerm.permission_id == - Permission.permission_id)\ - .join( - TargetUserGroup, - UserGroupUserGroupToPerm.target_user_group_id == - TargetUserGroup.users_group_id)\ - .join( - UserGroup, - UserGroupUserGroupToPerm.user_group_id == - UserGroup.users_group_id)\ - .join( - UserGroupMember, - UserGroupUserGroupToPerm.user_group_id == - UserGroupMember.users_group_id)\ - .filter( - UserGroupMember.user_id == user_id, - UserGroup.users_group_active == true()) + def get_default_user_group_perms_from_user_group(cls, user_id, user_group_id=None): + TargetUserGroup = aliased(UserGroup, name="target_user_group") + q = ( + Session() + .query(UserGroupUserGroupToPerm, UserGroup, Permission) + .join(Permission, UserGroupUserGroupToPerm.permission_id == Permission.permission_id) + .join(TargetUserGroup, UserGroupUserGroupToPerm.target_user_group_id == TargetUserGroup.users_group_id) + .join(UserGroup, UserGroupUserGroupToPerm.user_group_id == UserGroup.users_group_id) + .join(UserGroupMember, UserGroupUserGroupToPerm.user_group_id == UserGroupMember.users_group_id) + .filter(UserGroupMember.user_id == user_id, UserGroup.users_group_active == true()) + ) if user_group_id: - q = q.filter( - UserGroupUserGroupToPerm.user_group_id == user_group_id) + q = q.filter(UserGroupUserGroupToPerm.user_group_id == user_group_id) return q.all() class UserRepoToPerm(Base, BaseModel): - __tablename__ = 'repo_to_perm' + __tablename__ = "repo_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'repository_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "repository_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - repository = relationship('Repository') - permission = relationship('Permission') + user = relationship("User") + repository = relationship("Repository") + permission = relationship("Permission") @classmethod def create(cls, user, repository, permission): @@ -2753,24 +2671,29 @@ class UserRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.repository) + return "<%s => %s >" % (self.user, self.repository) class UserUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_user_group_to_perm' + __tablename__ = "user_user_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'user_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "user_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_user_group_to_perm_id = Column( + "user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_user_group_to_perm_id = Column("user_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - user = relationship('User') - user_group = relationship('UserGroup') - permission = relationship('Permission') + user = relationship("User") + user_group = relationship("UserGroup") + permission = relationship("Permission") @classmethod def create(cls, user, user_group, permission): @@ -2782,42 +2705,55 @@ class UserUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u'<%s => %s >' % (self.user, self.user_group) + return "<%s => %s >" % (self.user, self.user_group) class UserToPerm(Base, BaseModel): - __tablename__ = 'user_to_perm' + __tablename__ = "user_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - permission = relationship('Permission', lazy='joined') + user = relationship("User") + permission = relationship("Permission", lazy="joined") def __unicode__(self): - return u'<%s => %s >' % (self.user, self.permission) + return "<%s => %s >" % (self.user, self.permission) class UserGroupRepoToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_to_perm' + __tablename__ = "users_group_repo_to_perm" __table_args__ = ( - UniqueConstraint('repository_id', 'users_group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("repository_id", "users_group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') - repository = relationship('Repository') + users_group = relationship("UserGroup") + permission = relationship("Permission") + repository = relationship("Repository") @classmethod def create(cls, users_group, repository, permission): @@ -2829,25 +2765,41 @@ class UserGroupRepoToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.repository) + return " %s >" % (self.users_group, self.repository) class UserGroupUserGroupToPerm(Base, BaseModel): - __tablename__ = 'user_group_user_group_to_perm' + __tablename__ = "user_group_user_group_to_perm" __table_args__ = ( - UniqueConstraint('target_user_group_id', 'user_group_id', 'permission_id'), - CheckConstraint('target_user_group_id != user_group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("target_user_group_id", "user_group_id", "permission_id"), + CheckConstraint("target_user_group_id != user_group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + user_group_user_group_to_perm_id = Column( + "user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + target_user_group_id = Column( + "target_user_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + user_group_id = Column( + "user_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False, unique=None, default=None ) - user_group_user_group_to_perm_id = Column("user_group_user_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - target_user_group_id = Column("target_user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - user_group_id = Column("user_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - target_user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id') - user_group = relationship('UserGroup', primaryjoin='UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id') - permission = relationship('Permission') + target_user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.target_user_group_id==UserGroup.users_group_id" + ) + user_group = relationship( + "UserGroup", primaryjoin="UserGroupUserGroupToPerm.user_group_id==UserGroup.users_group_id" + ) + permission = relationship("Permission") @classmethod def create(cls, target_user_group, user_group, permission): @@ -2859,40 +2811,56 @@ class UserGroupUserGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.target_user_group, self.user_group) + return " %s >" % (self.target_user_group, self.user_group) class UserGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_to_perm' + __tablename__ = "users_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'permission_id',), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint( + "users_group_id", + "permission_id", + ), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, + ) + users_group_to_perm_id = Column( + "users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None ) - users_group_to_perm_id = Column("users_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) - users_group = relationship('UserGroup') - permission = relationship('Permission') + users_group = relationship("UserGroup") + permission = relationship("Permission") class UserRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'user_repo_group_to_perm' + __tablename__ = "user_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('user_id', 'group_id', 'permission_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "group_id", "permission_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - group_to_perm_id = Column("group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + group_to_perm_id = Column( + "group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - user = relationship('User') - group = relationship('RepoGroup') - permission = relationship('Permission') + user = relationship("User") + group = relationship("RepoGroup") + permission = relationship("Permission") @classmethod def create(cls, user, repository_group, permission): @@ -2905,21 +2873,31 @@ class UserRepoGroupToPerm(Base, BaseModel): class UserGroupRepoGroupToPerm(Base, BaseModel): - __tablename__ = 'users_group_repo_group_to_perm' + __tablename__ = "users_group_repo_group_to_perm" __table_args__ = ( - UniqueConstraint('users_group_id', 'group_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("users_group_id", "group_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - users_group_repo_group_to_perm_id = Column("users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - users_group_id = Column("users_group_id", Integer(), ForeignKey('users_groups.users_group_id'), nullable=False, unique=None, default=None) - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey('permissions.permission_id'), nullable=False, unique=None, default=None) + users_group_repo_group_to_perm_id = Column( + "users_group_repo_group_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + users_group_id = Column( + "users_group_id", + Integer(), + ForeignKey("users_groups.users_group_id"), + nullable=False, + unique=None, + default=None, + ) + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) - users_group = relationship('UserGroup') - permission = relationship('Permission') - group = relationship('RepoGroup') + users_group = relationship("UserGroup") + permission = relationship("Permission") + group = relationship("RepoGroup") @classmethod def create(cls, user_group, repository_group, permission): @@ -2931,44 +2909,55 @@ class UserGroupRepoGroupToPerm(Base, BaseModel): return n def __unicode__(self): - return u' %s >' % (self.users_group, self.group) + return " %s >" % (self.users_group, self.group) class Statistics(Base, BaseModel): - __tablename__ = 'statistics' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "statistics" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(1000000), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(1000000), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(1000000), nullable=False) # JSON data - repository = relationship('Repository', single_parent=True) + repository = relationship("Repository", single_parent=True) class UserFollowing(Base, BaseModel): - __tablename__ = 'user_followings' + __tablename__ = "user_followings" __table_args__ = ( - UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey('repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey('users.user_id'), nullable=True, unique=None, default=None) - follows_from = Column('follows_from', DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) - user = relationship('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relationship("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relationship('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relationship('Repository', order_by='Repository.repo_name') + follows_user = relationship("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relationship("Repository", order_by="Repository.repo_name") @classmethod def get_repo_followers(cls, repo_id): @@ -2976,31 +2965,28 @@ class UserFollowing(Base, BaseModel): class CacheKey(Base, BaseModel): - __tablename__ = 'cache_invalidation' + __tablename__ = "cache_invalidation" __table_args__ = ( - UniqueConstraint('cache_key'), - Index('key_idx', 'cache_key'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + UniqueConstraint("cache_key"), + Index("key_idx", "cache_key"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - CACHE_TYPE_ATOM = 'ATOM' - CACHE_TYPE_RSS = 'RSS' - CACHE_TYPE_README = 'README' + CACHE_TYPE_ATOM = "ATOM" + CACHE_TYPE_RSS = "RSS" + CACHE_TYPE_README = "README" cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) cache_key = Column("cache_key", String(255), nullable=True, unique=None, default=None) cache_args = Column("cache_args", String(255), nullable=True, unique=None, default=None) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False def __unicode__(self): - return u"<%s('%s:%s[%s]')>" % ( - self.__class__.__name__, - self.cache_id, self.cache_key, self.cache_active) + return "<%s('%s:%s[%s]')>" % (self.__class__.__name__, self.cache_id, self.cache_key, self.cache_active) def _cache_key_partition(self): prefix, repo_name, suffix = self.cache_key.partition(self.cache_args) @@ -3042,13 +3028,13 @@ class CacheKey(Base, BaseModel): instance_id from .ini file. """ import rhodecode - prefix = safe_str(rhodecode.CONFIG.get('instance_id') or '') + + prefix = safe_str(rhodecode.CONFIG.get("instance_id") or "") repo_as_unicode = safe_str(repo_name) - key = u'{}_{}'.format(repo_as_unicode, cache_type) \ - if cache_type else repo_as_unicode + key = "{}_{}".format(repo_as_unicode, cache_type) if cache_type else repo_as_unicode - return u'{}{}'.format(prefix, key) + return "{}{}".format(prefix, key) @classmethod def set_invalidate(cls, repo_name, delete=False): @@ -3059,19 +3045,15 @@ class CacheKey(Base, BaseModel): try: qry = Session().query(cls).filter(cls.cache_args == repo_name) if delete: - log.debug('cache objects deleted for repo %s', - safe_str(repo_name)) + log.debug("cache objects deleted for repo %s", safe_str(repo_name)) qry.delete() else: - log.debug('cache objects marked as invalid for repo %s', - safe_str(repo_name)) + log.debug("cache objects marked as invalid for repo %s", safe_str(repo_name)) qry.update({"cache_active": False}) Session().commit() except Exception: - log.exception( - 'Cache key invalidation failed for repository %s', - safe_str(repo_name)) + log.exception("Cache key invalidation failed for repository %s", safe_str(repo_name)) Session().rollback() @classmethod @@ -3083,41 +3065,44 @@ class CacheKey(Base, BaseModel): class ChangesetComment(Base, BaseModel): - __tablename__ = 'changeset_comments' + __tablename__ = "changeset_comments" __table_args__ = ( - Index('cc_revision_idx', 'revision'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("cc_revision_idx", "revision"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - COMMENT_OUTDATED = u'comment_outdated' - COMMENT_TYPE_NOTE = u'note' - COMMENT_TYPE_TODO = u'todo' + COMMENT_OUTDATED = "comment_outdated" + COMMENT_TYPE_NOTE = "note" + COMMENT_TYPE_TODO = "todo" COMMENT_TYPES = [COMMENT_TYPE_NOTE, COMMENT_TYPE_TODO] - comment_id = Column('comment_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - revision = Column('revision', String(40), nullable=True) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) - pull_request_version_id = Column("pull_request_version_id", Integer(), ForeignKey('pull_request_versions.pull_request_version_id'), nullable=True) - line_no = Column('line_no', Unicode(10), nullable=True) - hl_lines = Column('hl_lines', Unicode(512), nullable=True) - f_path = Column('f_path', Unicode(1000), nullable=True) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=False) - text = Column('text', UnicodeText().with_variant(UnicodeText(25000), 'mysql'), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - renderer = Column('renderer', Unicode(64), nullable=True) - display_state = Column('display_state', Unicode(128), nullable=True) + comment_id = Column("comment_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + revision = Column("revision", String(40), nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) + pull_request_version_id = Column( + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) + line_no = Column("line_no", Unicode(10), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) + f_path = Column("f_path", Unicode(1000), nullable=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) + text = Column("text", UnicodeText().with_variant(UnicodeText(25000), "mysql"), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + renderer = Column("renderer", Unicode(64), nullable=True) + display_state = Column("display_state", Unicode(128), nullable=True) - comment_type = Column('comment_type', Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) - resolved_comment_id = Column('resolved_comment_id', Integer(), ForeignKey('changeset_comments.comment_id'), nullable=True) - resolved_comment = relationship('ChangesetComment', remote_side=comment_id, backref='resolved_by') - author = relationship('User', lazy='joined') - repo = relationship('Repository') - status_change = relationship('ChangesetStatus', cascade="all, delete, delete-orphan", lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') - pull_request_version = relationship('PullRequestVersion') + comment_type = Column("comment_type", Unicode(128), nullable=True, default=COMMENT_TYPE_NOTE) + resolved_comment_id = Column( + "resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True + ) + resolved_comment = relationship("ChangesetComment", remote_side=comment_id, backref="resolved_by") + author = relationship("User", lazy="joined") + repo = relationship("Repository") + status_change = relationship("ChangesetStatus", cascade="all, delete, delete-orphan", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") + pull_request_version = relationship("PullRequestVersion") @classmethod def get_users(cls, revision=None, pull_request_id=None): @@ -3128,8 +3113,7 @@ class ChangesetComment(Base, BaseModel): :param cls: :param revision: """ - q = Session().query(User)\ - .join(ChangesetComment.author) + q = Session().query(User).join(ChangesetComment.author) if revision: q = q.filter(cls.revision == revision) elif pull_request_id: @@ -3140,7 +3124,7 @@ class ChangesetComment(Base, BaseModel): def get_index_from_version(cls, pr_version, versions): num_versions = [x.pull_request_version_id for x in versions] try: - return num_versions.index(pr_version) +1 + return num_versions.index(pr_version) + 1 except (IndexError, ValueError): return @@ -3176,26 +3160,25 @@ class ChangesetComment(Base, BaseModel): return self.line_no and self.f_path def get_index_version(self, versions): - return self.get_index_from_version( - self.pull_request_version_id, versions) + return self.get_index_from_version(self.pull_request_version_id, versions) def __repr__(self): if self.comment_id: - return '' % self.comment_id + return "" % self.comment_id else: - return '' % id(self) + return "" % id(self) def get_api_data(self): comment = self data = { - 'comment_id': comment.comment_id, - 'comment_type': comment.comment_type, - 'comment_text': comment.text, - 'comment_status': comment.status_change, - 'comment_f_path': comment.f_path, - 'comment_lineno': comment.line_no, - 'comment_author': comment.author, - 'comment_created_on': comment.created_on + "comment_id": comment.comment_id, + "comment_type": comment.comment_type, + "comment_text": comment.text, + "comment_status": comment.status_change, + "comment_f_path": comment.f_path, + "comment_lineno": comment.line_no, + "comment_author": comment.author, + "comment_created_on": comment.created_on, } return data @@ -3206,18 +3189,17 @@ class ChangesetComment(Base, BaseModel): class ChangesetStatus(Base, BaseModel): - __tablename__ = 'changeset_statuses' + __tablename__ = "changeset_statuses" __table_args__ = ( - Index('cs_revision_idx', 'revision'), - Index('cs_version_idx', 'version'), - UniqueConstraint('repo_id', 'revision', 'version'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("cs_revision_idx", "revision"), + Index("cs_version_idx", "version"), + UniqueConstraint("repo_id", "revision", "version"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - STATUS_NOT_REVIEWED = DEFAULT = 'not_reviewed' - STATUS_APPROVED = 'approved' - STATUS_REJECTED = 'rejected' - STATUS_UNDER_REVIEW = 'under_review' + STATUS_NOT_REVIEWED = DEFAULT = "not_reviewed" + STATUS_APPROVED = "approved" + STATUS_REJECTED = "rejected" + STATUS_UNDER_REVIEW = "under_review" STATUSES = [ (STATUS_NOT_REVIEWED, _("Not Reviewed")), # (no icon) and default @@ -3226,26 +3208,23 @@ class ChangesetStatus(Base, BaseModel): (STATUS_UNDER_REVIEW, _("Under Review")), ] - changeset_status_id = Column('changeset_status_id', Integer(), nullable=False, primary_key=True) - repo_id = Column('repo_id', Integer(), ForeignKey('repositories.repo_id'), nullable=False) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None) - revision = Column('revision', String(40), nullable=False) - status = Column('status', String(128), nullable=False, default=DEFAULT) - changeset_comment_id = Column('changeset_comment_id', Integer(), ForeignKey('changeset_comments.comment_id')) - modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now) - version = Column('version', Integer(), nullable=False, default=0) - pull_request_id = Column("pull_request_id", Integer(), ForeignKey('pull_requests.pull_request_id'), nullable=True) + changeset_status_id = Column("changeset_status_id", Integer(), nullable=False, primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) + revision = Column("revision", String(40), nullable=False) + status = Column("status", String(128), nullable=False, default=DEFAULT) + changeset_comment_id = Column("changeset_comment_id", Integer(), ForeignKey("changeset_comments.comment_id")) + modified_at = Column("modified_at", DateTime(), nullable=False, default=datetime.datetime.now) + version = Column("version", Integer(), nullable=False, default=0) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) - author = relationship('User', lazy='joined') - repo = relationship('Repository') - comment = relationship('ChangesetComment', lazy='joined') - pull_request = relationship('PullRequest', lazy='joined') + author = relationship("User", lazy="joined") + repo = relationship("Repository") + comment = relationship("ChangesetComment", lazy="joined") + pull_request = relationship("PullRequest", lazy="joined") def __unicode__(self): - return u"<%s('%s[v%s]:%s')>" % ( - self.__class__.__name__, - self.status, self.version, self.author - ) + return "<%s('%s[v%s]:%s')>" % (self.__class__.__name__, self.status, self.version, self.author) @classmethod def get_status_lbl(cls, value): @@ -3258,8 +3237,8 @@ class ChangesetStatus(Base, BaseModel): def get_api_data(self): status = self data = { - 'status_id': status.changeset_status_id, - 'status': status.status, + "status_id": status.changeset_status_id, + "status": status.status, } return data @@ -3275,64 +3254,49 @@ class _PullRequestBase(BaseModel): """ # .status values - STATUS_NEW = u'new' - STATUS_OPEN = u'open' - STATUS_CLOSED = u'closed' + STATUS_NEW = "new" + STATUS_OPEN = "open" + STATUS_CLOSED = "closed" - title = Column('title', Unicode(255), nullable=True) - description = Column( - 'description', UnicodeText().with_variant(UnicodeText(10240), 'mysql'), - nullable=True) + title = Column("title", Unicode(255), nullable=True) + description = Column("description", UnicodeText().with_variant(UnicodeText(10240), "mysql"), nullable=True) # new/open/closed status of pull request (not approve/reject/etc) - status = Column('status', Unicode(255), nullable=False, default=STATUS_NEW) - created_on = Column( - 'created_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) - updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + status = Column("status", Unicode(255), nullable=False, default=STATUS_NEW) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) @declared_attr def user_id(cls): - return Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=False, - unique=None) + return Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None) # 500 revisions max - _revisions = Column( - 'revisions', UnicodeText().with_variant(UnicodeText(20500), 'mysql')) + _revisions = Column("revisions", UnicodeText().with_variant(UnicodeText(20500), "mysql")) @declared_attr def source_repo_id(cls): # TODO: dan: rename column to source_repo_id - return Column( - 'org_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("org_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - source_ref = Column('org_ref', Unicode(255), nullable=False) + source_ref = Column("org_ref", Unicode(255), nullable=False) @declared_attr def target_repo_id(cls): # TODO: dan: rename column to target_repo_id - return Column( - 'other_repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=False) + return Column("other_repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False) - target_ref = Column('other_ref', Unicode(255), nullable=False) - _shadow_merge_ref = Column('shadow_merge_ref', Unicode(255), nullable=True) + target_ref = Column("other_ref", Unicode(255), nullable=False) + _shadow_merge_ref = Column("shadow_merge_ref", Unicode(255), nullable=True) # TODO: dan: rename column to last_merge_source_rev - _last_merge_source_rev = Column( - 'last_merge_org_rev', String(40), nullable=True) + _last_merge_source_rev = Column("last_merge_org_rev", String(40), nullable=True) # TODO: dan: rename column to last_merge_target_rev - _last_merge_target_rev = Column( - 'last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_target_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) reviewer_data = Column( - 'reviewer_data_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + "reviewer_data_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + ) @property def reviewer_data_json(self): @@ -3341,15 +3305,16 @@ class _PullRequestBase(BaseModel): @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.description) @hybrid_property def revisions(self): - return self._revisions.split(':') if self._revisions else [] + return self._revisions.split(":") if self._revisions else [] @revisions.setter def revisions(self, val): - self._revisions = ':'.join(val) + self._revisions = ":".join(val) @hybrid_property def last_merge_status(self): @@ -3361,13 +3326,11 @@ class _PullRequestBase(BaseModel): @declared_attr def author(cls): - return relationship('User', lazy='joined') + return relationship("User", lazy="joined") @declared_attr def source_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.source_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.source_repo_id==Repository.repo_id" % cls.__name__) @property def source_ref_parts(self): @@ -3375,9 +3338,7 @@ class _PullRequestBase(BaseModel): @declared_attr def target_repo(cls): - return relationship( - 'Repository', - primaryjoin='%s.target_repo_id==Repository.repo_id' % cls.__name__) + return relationship("Repository", primaryjoin="%s.target_repo_id==Repository.repo_id" % cls.__name__) @property def target_ref_parts(self): @@ -3397,7 +3358,7 @@ class _PullRequestBase(BaseModel): If unicode evaluates to False it returns None. """ if raw: - refs = raw.split(':') + refs = raw.split(":") return Reference(*refs) else: return None @@ -3408,7 +3369,7 @@ class _PullRequestBase(BaseModel): If reference is None it returns None. """ if ref: - return u':'.join(ref) + return ":".join(ref) else: return None @@ -3419,97 +3380,82 @@ class _PullRequestBase(BaseModel): if with_merge_state: merge_status = PullRequestModel().merge_status(pull_request) merge_state = { - 'status': merge_status[0], - 'message': safe_str(merge_status[1]), + "status": merge_status[0], + "message": safe_str(merge_status[1]), } else: - merge_state = {'status': 'not_available', - 'message': 'not_available'} + merge_state = {"status": "not_available", "message": "not_available"} merge_data = { - 'clone_url': PullRequestModel().get_shadow_clone_url(pull_request), - 'reference': ( - pull_request.shadow_merge_ref._asdict() - if pull_request.shadow_merge_ref else None), + "clone_url": PullRequestModel().get_shadow_clone_url(pull_request), + "reference": (pull_request.shadow_merge_ref._asdict() if pull_request.shadow_merge_ref else None), } data = { - 'pull_request_id': pull_request.pull_request_id, - 'url': PullRequestModel().get_url(pull_request), - 'title': pull_request.title, - 'description': pull_request.description, - 'status': pull_request.status, - 'created_on': pull_request.created_on, - 'updated_on': pull_request.updated_on, - 'commit_ids': pull_request.revisions, - 'review_status': pull_request.calculated_review_status(), - 'mergeable': merge_state, - 'source': { - 'clone_url': pull_request.source_repo.clone_url(), - 'repository': pull_request.source_repo.repo_name, - 'reference': { - 'name': pull_request.source_ref_parts.name, - 'type': pull_request.source_ref_parts.type, - 'commit_id': pull_request.source_ref_parts.commit_id, + "pull_request_id": pull_request.pull_request_id, + "url": PullRequestModel().get_url(pull_request), + "title": pull_request.title, + "description": pull_request.description, + "status": pull_request.status, + "created_on": pull_request.created_on, + "updated_on": pull_request.updated_on, + "commit_ids": pull_request.revisions, + "review_status": pull_request.calculated_review_status(), + "mergeable": merge_state, + "source": { + "clone_url": pull_request.source_repo.clone_url(), + "repository": pull_request.source_repo.repo_name, + "reference": { + "name": pull_request.source_ref_parts.name, + "type": pull_request.source_ref_parts.type, + "commit_id": pull_request.source_ref_parts.commit_id, }, }, - 'target': { - 'clone_url': pull_request.target_repo.clone_url(), - 'repository': pull_request.target_repo.repo_name, - 'reference': { - 'name': pull_request.target_ref_parts.name, - 'type': pull_request.target_ref_parts.type, - 'commit_id': pull_request.target_ref_parts.commit_id, + "target": { + "clone_url": pull_request.target_repo.clone_url(), + "repository": pull_request.target_repo.repo_name, + "reference": { + "name": pull_request.target_ref_parts.name, + "type": pull_request.target_ref_parts.type, + "commit_id": pull_request.target_ref_parts.commit_id, }, }, - 'merge': merge_data, - 'author': pull_request.author.get_api_data(include_secrets=False, - details='basic'), - 'reviewers': [ + "merge": merge_data, + "author": pull_request.author.get_api_data(include_secrets=False, details="basic"), + "reviewers": [ { - 'user': reviewer.get_api_data(include_secrets=False, - details='basic'), - 'reasons': reasons, - 'review_status': st[0][1].status if st else 'not_reviewed', + "user": reviewer.get_api_data(include_secrets=False, details="basic"), + "reasons": reasons, + "review_status": st[0][1].status if st else "not_reviewed", } - for reviewer, reasons, mandatory, st in - pull_request.reviewers_statuses() - ] + for reviewer, reasons, mandatory, st in pull_request.reviewers_statuses() + ], } return data class PullRequest(Base, _PullRequestBase): - __tablename__ = 'pull_requests' + __tablename__ = "pull_requests" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_id = Column( - 'pull_request_id', Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), nullable=False, primary_key=True) def __repr__(self): if self.pull_request_id: - return '' % self.pull_request_id + return "" % self.pull_request_id else: - return '' % id(self) + return "" % id(self) - reviewers = relationship('PullRequestReviewers', - cascade="all, delete, delete-orphan") - statuses = relationship('ChangesetStatus', - cascade="all, delete, delete-orphan") - comments = relationship('ChangesetComment', - cascade="all, delete, delete-orphan") - versions = relationship('PullRequestVersion', - cascade="all, delete, delete-orphan", - lazy='dynamic') + reviewers = relationship("PullRequestReviewers", cascade="all, delete, delete-orphan") + statuses = relationship("ChangesetStatus", cascade="all, delete, delete-orphan") + comments = relationship("ChangesetComment", cascade="all, delete, delete-orphan") + versions = relationship("PullRequestVersion", cascade="all, delete, delete-orphan", lazy="dynamic") @classmethod - def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, - internal_methods=None): - + def get_pr_display_object(cls, pull_request_obj, org_pull_request_obj, internal_methods=None): class PullRequestDisplay(object): """ Special object wrapper for showing PullRequest data via Versions @@ -3520,7 +3466,7 @@ class PullRequest(Base, _PullRequestBase): def __init__(self, attrs, internal=None): self.attrs = attrs # internal have priority over the given ones via attrs - self.internal = internal or ['versions'] + self.internal = internal or ["versions"] def __getattr__(self, item): if item in self.internal: @@ -3528,35 +3474,30 @@ class PullRequest(Base, _PullRequestBase): try: return self.attrs[item] except KeyError: - raise AttributeError( - '%s object has no attribute %s' % (self, item)) + raise AttributeError("%s object has no attribute %s" % (self, item)) def __repr__(self): - return '' % self.attrs.get('pull_request_id') + return "" % self.attrs.get("pull_request_id") def versions(self): - return pull_request_obj.versions.order_by( - PullRequestVersion.pull_request_version_id).all() + return pull_request_obj.versions.order_by(PullRequestVersion.pull_request_version_id).all() def is_closed(self): return pull_request_obj.is_closed() @property def pull_request_version_id(self): - return getattr(pull_request_obj, 'pull_request_version_id', None) + return getattr(pull_request_obj, "pull_request_version_id", None) attrs = StrictAttributeDict(pull_request_obj.get_api_data()) - attrs.author = StrictAttributeDict( - pull_request_obj.author.get_api_data()) + attrs.author = StrictAttributeDict(pull_request_obj.author.get_api_data()) if pull_request_obj.target_repo: - attrs.target_repo = StrictAttributeDict( - pull_request_obj.target_repo.get_api_data()) + attrs.target_repo = StrictAttributeDict(pull_request_obj.target_repo.get_api_data()) attrs.target_repo.clone_url = pull_request_obj.target_repo.clone_url if pull_request_obj.source_repo: - attrs.source_repo = StrictAttributeDict( - pull_request_obj.source_repo.get_api_data()) + attrs.source_repo = StrictAttributeDict(pull_request_obj.source_repo.get_api_data()) attrs.source_repo.clone_url = pull_request_obj.source_repo.clone_url attrs.source_ref_parts = pull_request_obj.source_ref_parts @@ -3574,49 +3515,47 @@ class PullRequest(Base, _PullRequestBase): def __json__(self): return { - 'revisions': self.revisions, + "revisions": self.revisions, } def calculated_review_status(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().calculated_review_status(self) def reviewers_statuses(self): from rhodecode.model.changeset_status import ChangesetStatusModel + return ChangesetStatusModel().reviewers_statuses(self) @property def workspace_id(self): from rhodecode.model.pull_request import PullRequestModel + return PullRequestModel()._workspace_id(self) def get_shadow_repo(self): workspace_id = self.workspace_id vcs_obj = self.target_repo.scm_instance() - shadow_repository_path = vcs_obj._get_shadow_repository_path( - workspace_id) + shadow_repository_path = vcs_obj._get_shadow_repository_path(workspace_id) return vcs_obj.get_shadow_instance(shadow_repository_path) class PullRequestVersion(Base, _PullRequestBase): - __tablename__ = 'pull_request_versions' + __tablename__ = "pull_request_versions" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - pull_request_version_id = Column( - 'pull_request_version_id', Integer(), nullable=False, primary_key=True) - pull_request_id = Column( - 'pull_request_id', Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - pull_request = relationship('PullRequest') + pull_request_version_id = Column("pull_request_version_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + pull_request = relationship("PullRequest") def __repr__(self): if self.pull_request_version_id: - return '' % self.pull_request_version_id + return "" % self.pull_request_version_id else: - return '' % id(self) + return "" % id(self) @property def reviewers(self): @@ -3638,10 +3577,9 @@ class PullRequestVersion(Base, _PullRequestBase): class PullRequestReviewers(Base, BaseModel): - __tablename__ = 'pull_request_reviewers' + __tablename__ = "pull_request_reviewers" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) @hybrid_property @@ -3654,56 +3592,51 @@ class PullRequestReviewers(Base, BaseModel): def reasons(self, val): val = val or [] if any(not isinstance(x, str) for x in val): - raise Exception('invalid reasons type, must be list of strings') + raise Exception("invalid reasons type, must be list of strings") self._reasons = val - pull_requests_reviewers_id = Column( - 'pull_requests_reviewers_id', Integer(), nullable=False, - primary_key=True) - pull_request_id = Column( - "pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), nullable=False) - user_id = Column( - "user_id", Integer(), ForeignKey('users.user_id'), nullable=True) - _reasons = Column( - 'reason', MutationList.as_mutable( - JsonType('list', dialect_map=dict(mysql=UnicodeText(16384))))) + pull_requests_reviewers_id = Column("pull_requests_reviewers_id", Integer(), nullable=False, primary_key=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=False) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + _reasons = Column("reason", MutationList.as_mutable(JsonType("list", dialect_map=dict(mysql=UnicodeText(16384))))) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') - pull_request = relationship('PullRequest') + user = relationship("User") + pull_request = relationship("PullRequest") class Notification(Base, BaseModel): - __tablename__ = 'notifications' + __tablename__ = "notifications" __table_args__ = ( - Index('notification_type_idx', 'type'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + Index("notification_type_idx", "type"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - TYPE_CHANGESET_COMMENT = u'cs_comment' - TYPE_MESSAGE = u'message' - TYPE_MENTION = u'mention' - TYPE_REGISTRATION = u'registration' - TYPE_PULL_REQUEST = u'pull_request' - TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment' + TYPE_CHANGESET_COMMENT = "cs_comment" + TYPE_MESSAGE = "message" + TYPE_MENTION = "mention" + TYPE_REGISTRATION = "registration" + TYPE_PULL_REQUEST = "pull_request" + TYPE_PULL_REQUEST_COMMENT = "pull_request_comment" - notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True) - subject = Column('subject', Unicode(512), nullable=True) - body = Column('body', UnicodeText().with_variant(UnicodeText(50000), 'mysql'), nullable=True) - created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - type_ = Column('type', Unicode(255)) + notification_id = Column("notification_id", Integer(), nullable=False, primary_key=True) + subject = Column("subject", Unicode(512), nullable=True) + body = Column("body", UnicodeText().with_variant(UnicodeText(50000), "mysql"), nullable=True) + created_by = Column("created_by", Integer(), ForeignKey("users.user_id"), nullable=True) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + type_ = Column("type", Unicode(255)) - created_by_user = relationship('User') - notifications_to_users = relationship('UserNotification', lazy='joined', - cascade="all, delete, delete-orphan") + created_by_user = relationship("User") + notifications_to_users = relationship("UserNotification", lazy="joined", cascade="all, delete, delete-orphan") @property def recipients(self): - return [x.user for x in UserNotification.query()\ - .filter(UserNotification.notification == self)\ - .order_by(UserNotification.user_id.asc()).all()] + return [ + x.user + for x in UserNotification.query() + .filter(UserNotification.notification == self) + .order_by(UserNotification.user_id.asc()) + .all() + ] @classmethod def create(cls, created_by, subject, body, recipients, type_=None): @@ -3733,20 +3666,24 @@ class Notification(Base, BaseModel): class UserNotification(Base, BaseModel): - __tablename__ = 'user_to_notification' + __tablename__ = "user_to_notification" __table_args__ = ( - UniqueConstraint('user_id', 'notification_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + UniqueConstraint("user_id", "notification_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - user_id = Column('user_id', Integer(), ForeignKey('users.user_id'), primary_key=True) - notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), primary_key=True) - read = Column('read', Boolean, default=False) - sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + notification_id = Column( + "notification_id", Integer(), ForeignKey("notifications.notification_id"), primary_key=True + ) + read = Column("read", Boolean, default=False) + sent_on = Column("sent_on", DateTime(timezone=False), nullable=True, unique=None) - user = relationship('User', lazy="joined") - notification = relationship('Notification', lazy="joined", - order_by=lambda: Notification.created_on.desc(),) + user = relationship("User", lazy="joined") + notification = relationship( + "Notification", + lazy="joined", + order_by=lambda: Notification.created_on.desc(), + ) def mark_as_read(self): self.read = True @@ -3754,38 +3691,38 @@ class UserNotification(Base, BaseModel): class Gist(Base, BaseModel): - __tablename__ = 'gists' + __tablename__ = "gists" __table_args__ = ( - Index('g_gist_access_id_idx', 'gist_access_id'), - Index('g_created_on_idx', 'created_on'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} + Index("g_gist_access_id_idx", "gist_access_id"), + Index("g_created_on_idx", "created_on"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - GIST_PUBLIC = u'public' - GIST_PRIVATE = u'private' - DEFAULT_FILENAME = u'gistfile1.txt' + GIST_PUBLIC = "public" + GIST_PRIVATE = "private" + DEFAULT_FILENAME = "gistfile1.txt" - ACL_LEVEL_PUBLIC = u'acl_public' - ACL_LEVEL_PRIVATE = u'acl_private' + ACL_LEVEL_PUBLIC = "acl_public" + ACL_LEVEL_PRIVATE = "acl_private" - gist_id = Column('gist_id', Integer(), primary_key=True) - gist_access_id = Column('gist_access_id', Unicode(250)) - gist_description = Column('gist_description', UnicodeText().with_variant(UnicodeText(1024), 'mysql')) - gist_owner = Column('user_id', Integer(), ForeignKey('users.user_id'), nullable=True) - gist_expires = Column('gist_expires', Float(53), nullable=False) - gist_type = Column('gist_type', Unicode(128), nullable=False) - created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, default=datetime.datetime.now) - acl_level = Column('acl_level', Unicode(128), nullable=True) + gist_id = Column("gist_id", Integer(), primary_key=True) + gist_access_id = Column("gist_access_id", Unicode(250)) + gist_description = Column("gist_description", UnicodeText().with_variant(UnicodeText(1024), "mysql")) + gist_owner = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True) + gist_expires = Column("gist_expires", Float(53), nullable=False) + gist_type = Column("gist_type", Unicode(128), nullable=False) + created_on = Column("created_on", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) + acl_level = Column("acl_level", Unicode(128), nullable=True) - owner = relationship('User') + owner = relationship("User") def __repr__(self): - return '' % (self.gist_type, self.gist_access_id) + return "" % (self.gist_type, self.gist_access_id) @hybrid_property def description_safe(self): from rhodecode.lib import helpers as h + return h.escape(self.gist_description) @classmethod @@ -3803,6 +3740,7 @@ class Gist(Base, BaseModel): def gist_url(self): from rhodecode.model.gist import GistModel + return GistModel().get_url(self) @classmethod @@ -3813,8 +3751,8 @@ class Gist(Base, BaseModel): :param cls: """ from rhodecode.model.gist import GIST_STORE_LOC - q = Session().query(RhodeCodeUi)\ - .filter(RhodeCodeUi.ui_key == URL_SEP) + + q = Session().query(RhodeCodeUi).filter(RhodeCodeUi.ui_key == URL_SEP) q = q.options(FromCache("sql_cache_short", "repository_repo_path")) return os.path.join(q.one().ui_value, GIST_STORE_LOC) @@ -3824,54 +3762,49 @@ class Gist(Base, BaseModel): """ gist = self data = { - 'gist_id': gist.gist_id, - 'type': gist.gist_type, - 'access_id': gist.gist_access_id, - 'description': gist.gist_description, - 'url': gist.gist_url(), - 'expires': gist.gist_expires, - 'created_on': gist.created_on, - 'modified_at': gist.modified_at, - 'content': None, - 'acl_level': gist.acl_level, + "gist_id": gist.gist_id, + "type": gist.gist_type, + "access_id": gist.gist_access_id, + "description": gist.gist_description, + "url": gist.gist_url(), + "expires": gist.gist_expires, + "created_on": gist.created_on, + "modified_at": gist.modified_at, + "content": None, + "acl_level": gist.acl_level, } return data def __json__(self): - data = dict( - ) + data = dict() data.update(self.get_api_data()) return data + # SCM functions def scm_instance(self, **kwargs): full_repo_path = os.path.join(self.base_path(), self.gist_access_id) - return get_vcs_instance( - repo_path=safe_str(full_repo_path), create=False) + return get_vcs_instance(repo_path=safe_str(full_repo_path), create=False) class ExternalIdentity(Base, BaseModel): - __tablename__ = 'external_identities' + __tablename__ = "external_identities" __table_args__ = ( - Index('local_user_id_idx', 'local_user_id'), - Index('external_id_idx', 'external_id'), - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8'}) + Index("local_user_id_idx", "local_user_id"), + Index("external_id_idx", "external_id"), + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8"}, + ) - external_id = Column('external_id', Unicode(255), default=u'', - primary_key=True) - external_username = Column('external_username', Unicode(1024), default=u'') - local_user_id = Column('local_user_id', Integer(), - ForeignKey('users.user_id'), primary_key=True) - provider_name = Column('provider_name', Unicode(255), default=u'', - primary_key=True) - access_token = Column('access_token', String(1024), default=u'') - alt_token = Column('alt_token', String(1024), default=u'') - token_secret = Column('token_secret', String(1024), default=u'') + external_id = Column("external_id", Unicode(255), default="", primary_key=True) + external_username = Column("external_username", Unicode(1024), default="") + local_user_id = Column("local_user_id", Integer(), ForeignKey("users.user_id"), primary_key=True) + provider_name = Column("provider_name", Unicode(255), default="", primary_key=True) + access_token = Column("access_token", String(1024), default="") + alt_token = Column("alt_token", String(1024), default="") + token_secret = Column("token_secret", String(1024), default="") @classmethod - def by_external_id_and_provider(cls, external_id, provider_name, - local_user_id=None): + def by_external_id_and_provider(cls, external_id, provider_name, local_user_id=None): """ Returns ExternalIdentity instance based on search params @@ -3915,31 +3848,28 @@ class ExternalIdentity(Base, BaseModel): class Integration(Base, BaseModel): - __tablename__ = 'integrations' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True} - ) + __tablename__ = "integrations" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - integration_id = Column('integration_id', Integer(), primary_key=True) - integration_type = Column('integration_type', String(255)) - enabled = Column('enabled', Boolean(), nullable=False) - name = Column('name', String(255), nullable=False) - child_repos_only = Column('child_repos_only', Boolean(), nullable=False, - default=False) + integration_id = Column("integration_id", Integer(), primary_key=True) + integration_type = Column("integration_type", String(255)) + enabled = Column("enabled", Boolean(), nullable=False) + name = Column("name", String(255), nullable=False) + child_repos_only = Column("child_repos_only", Boolean(), nullable=False, default=False) - settings = Column( - 'settings_json', MutationObj.as_mutable( - JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) - repo = relationship('Repository', lazy='joined') + settings = Column("settings_json", MutationObj.as_mutable(JsonType(dialect_map=dict(mysql=UnicodeText(16384))))) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) + repo = relationship("Repository", lazy="joined") repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) - repo_group = relationship('RepoGroup', lazy='joined') + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) + repo_group = relationship("RepoGroup", lazy="joined") @property def scope(self): @@ -3947,97 +3877,99 @@ class Integration(Base, BaseModel): return repr(self.repo) if self.repo_group: if self.child_repos_only: - return repr(self.repo_group) + ' (child repos only)' + return repr(self.repo_group) + " (child repos only)" else: - return repr(self.repo_group) + ' (recursive)' + return repr(self.repo_group) + " (recursive)" if self.child_repos_only: - return 'root_repos' - return 'global' + return "root_repos" + return "global" def __repr__(self): - return '' % (self.integration_type, self.scope) + return "" % (self.integration_type, self.scope) class RepoReviewRuleUser(Base, BaseModel): - __tablename__ = 'repo_review_rules_users' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_user_id = Column('repo_review_rule_user_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False) + __tablename__ = "repo_review_rules_users" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_user_id = Column("repo_review_rule_user_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - user = relationship('User') + user = relationship("User") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRuleUserGroup(Base, BaseModel): - __tablename__ = 'repo_review_rules_users_groups' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) - repo_review_rule_users_group_id = Column('repo_review_rule_users_group_id', Integer(), primary_key=True) - repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey('repo_review_rules.repo_review_rule_id')) - users_group_id = Column("users_group_id", Integer(),ForeignKey('users_groups.users_group_id'), nullable=False) + __tablename__ = "repo_review_rules_users_groups" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } + repo_review_rule_users_group_id = Column("repo_review_rule_users_group_id", Integer(), primary_key=True) + repo_review_rule_id = Column("repo_review_rule_id", Integer(), ForeignKey("repo_review_rules.repo_review_rule_id")) + users_group_id = Column("users_group_id", Integer(), ForeignKey("users_groups.users_group_id"), nullable=False) mandatory = Column("mandatory", Boolean(), nullable=False, default=False) - users_group = relationship('UserGroup') + users_group = relationship("UserGroup") def rule_data(self): - return { - 'mandatory': self.mandatory - } + return {"mandatory": self.mandatory} class RepoReviewRule(Base, BaseModel): - __tablename__ = 'repo_review_rules' - __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True,} - ) + __tablename__ = "repo_review_rules" + __table_args__ = { + "extend_existing": True, + "mysql_engine": "InnoDB", + "mysql_charset": "utf8", + "sqlite_autoincrement": True, + } - repo_review_rule_id = Column( - 'repo_review_rule_id', Integer(), primary_key=True) - repo_id = Column( - "repo_id", Integer(), ForeignKey('repositories.repo_id')) - repo = relationship('Repository', backref='review_rules') + repo_review_rule_id = Column("repo_review_rule_id", Integer(), primary_key=True) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id")) + repo = relationship("Repository", backref="review_rules") - _branch_pattern = Column("branch_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob - _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') # glob + _branch_pattern = Column( + "branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) # glob + _file_pattern = Column("file_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*") # glob use_authors_for_review = Column("use_authors_for_review", Boolean(), nullable=False, default=False) forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=False, default=False) forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=False, default=False) forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=False, default=False) - rule_users = relationship('RepoReviewRuleUser') - rule_user_groups = relationship('RepoReviewRuleUserGroup') + rule_users = relationship("RepoReviewRuleUser") + rule_user_groups = relationship("RepoReviewRuleUserGroup") @hybrid_property def branch_pattern(self): - return self._branch_pattern or '*' + return self._branch_pattern or "*" def _validate_glob(self, value): - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") @branch_pattern.setter def branch_pattern(self, value): self._validate_glob(value) - self._branch_pattern = value or '*' + self._branch_pattern = value or "*" @hybrid_property def file_pattern(self): - return self._file_pattern or '*' + return self._file_pattern or "*" @file_pattern.setter def file_pattern(self, value): self._validate_glob(value) - self._file_pattern = value or '*' + self._file_pattern = value or "*" def matches(self, branch, files_changed): """ @@ -4047,16 +3979,16 @@ class RepoReviewRule(Base, BaseModel): :param files_changed: list of file paths changed in the pull request """ - branch = branch or '' + branch = branch or "" files_changed = files_changed or [] branch_matches = True if branch: - branch_regex = re.compile('^' + glob2re(self.branch_pattern) + '$') + branch_regex = re.compile("^" + glob2re(self.branch_pattern) + "$") branch_matches = bool(branch_regex.search(branch)) files_matches = True - if self.file_pattern != '*': + if self.file_pattern != "*": files_matches = False file_regex = re.compile(glob2re(self.file_pattern)) for filename in files_changed: @@ -4068,7 +4000,7 @@ class RepoReviewRule(Base, BaseModel): @property def review_users(self): - """ Returns the users which this rule applies to """ + """Returns the users which this rule applies to""" users = collections.OrderedDict() @@ -4076,56 +4008,53 @@ class RepoReviewRule(Base, BaseModel): if rule_user.user.active: if rule_user.user not in users: users[rule_user.user.username] = { - 'user': rule_user.user, - 'source': 'user', - 'source_data': {}, - 'data': rule_user.rule_data() + "user": rule_user.user, + "source": "user", + "source_data": {}, + "data": rule_user.rule_data(), } for rule_user_group in self.rule_user_groups: source_data = { - 'name': rule_user_group.users_group.users_group_name, - 'members': len(rule_user_group.users_group.members) + "name": rule_user_group.users_group.users_group_name, + "members": len(rule_user_group.users_group.members), } for member in rule_user_group.users_group.members: if member.user.active: users[member.user.username] = { - 'user': member.user, - 'source': 'user_group', - 'source_data': source_data, - 'data': rule_user_group.rule_data() + "user": member.user, + "source": "user_group", + "source_data": source_data, + "data": rule_user_group.rule_data(), } return users def __repr__(self): - return '' % ( - self.repo_review_rule_id, self.repo) + return "" % (self.repo_review_rule_id, self.repo) class DbMigrateVersion(Base, BaseModel): - __tablename__ = 'db_migrate_version' + __tablename__ = "db_migrate_version" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) - repository_id = Column('repository_id', String(250), primary_key=True) - repository_path = Column('repository_path', Text) - version = Column('version', Integer) + repository_id = Column("repository_id", String(250), primary_key=True) + repository_path = Column("repository_path", Text) + version = Column("version", Integer) class DbSession(Base, BaseModel): - __tablename__ = 'db_session' + __tablename__ = "db_session" __table_args__ = ( - {'extend_existing': True, 'mysql_engine': 'InnoDB', - 'mysql_charset': 'utf8', 'sqlite_autoincrement': True}, + {"extend_existing": True, "mysql_engine": "InnoDB", "mysql_charset": "utf8", "sqlite_autoincrement": True}, ) def __repr__(self): - return ''.format(self.id) + return "".format(self.id) - id = Column('id', Integer()) - namespace = Column('namespace', String(255), primary_key=True) - accessed = Column('accessed', DateTime, nullable=False) - created = Column('created', DateTime, nullable=False) - data = Column('data', PickleType, nullable=False) + id = Column("id", Integer()) + namespace = Column("namespace", String(255), primary_key=True) + accessed = Column("accessed", DateTime, nullable=False) + created = Column("created", DateTime, nullable=False) + data = Column("data", PickleType, nullable=False) diff --git a/rhodecode/lib/dbmigrate/utils.py b/rhodecode/lib/dbmigrate/utils.py index b7c912f9..71a42485 100644 --- a/rhodecode/lib/dbmigrate/utils.py +++ b/rhodecode/lib/dbmigrate/utils.py @@ -31,23 +31,21 @@ def create_default_permissions(_SESSION, db): def create_default_object_permission(_SESSION, db): - obj = db.User.get_by_username(db.User.DEFAULT_USER) obj_perms = db.UserToPerm.query().filter(db.UserToPerm.user == obj).all() def _get_group(perm_name): - return '.'.join(perm_name.split('.')[:1]) + return ".".join(perm_name.split(".")[:1]) - defined_perms_groups = list(map( - _get_group, (x.permission.permission_name for x in obj_perms))) - log.debug('GOT ALREADY DEFINED:%s', obj_perms) + defined_perms_groups = list(map(_get_group, (x.permission.permission_name for x in obj_perms))) + log.debug("GOT ALREADY DEFINED:%s", obj_perms) # for every default permission that needs to be created, we check if # it's group is already defined, if it's not we create default perm for perm_name in db.Permission.DEFAULT_USER_PERMISSIONS: gr = _get_group(perm_name) if gr not in defined_perms_groups: - log.debug('GR:%s not found, creating permission %s', gr, perm_name) + log.debug("GR:%s not found, creating permission %s", gr, perm_name) new_perm = db.UserToPerm() new_perm.user = obj new_perm.permission = db.Permission.get_by_key(perm_name) diff --git a/rhodecode/lib/dbmigrate/versions/001_initial_release.py b/rhodecode/lib/dbmigrate/versions/001_initial_release.py index 80934192..fd0aadeb 100644 --- a/rhodecode/lib/dbmigrate/versions/001_initial_release.py +++ b/rhodecode/lib/dbmigrate/versions/001_initial_release.py @@ -1,6 +1,6 @@ -#============================================================================== +# ============================================================================== # DB INITIAL MODEL -#============================================================================== +# ============================================================================== import logging import datetime @@ -14,54 +14,145 @@ from rhodecode.lib.dbmigrate.migrate import * log = logging.getLogger(__name__) + class RhodeCodeSetting(Base): - __tablename__ = 'rhodecode_settings' - __table_args__ = (UniqueConstraint('app_settings_name'), {'useexisting':True}) + __tablename__ = "rhodecode_settings" + __table_args__ = (UniqueConstraint("app_settings_name"), {"useexisting": True}) app_settings_id = Column("app_settings_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - app_settings_name = Column("app_settings_name", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - app_settings_value = Column("app_settings_value", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) + app_settings_name = Column( + "app_settings_name", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + app_settings_value = Column( + "app_settings_value", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) def __init__(self, k, v): self.app_settings_name = k self.app_settings_value = v def __repr__(self): - return "" % (self.app_settings_name, - self.app_settings_value) + return "" % (self.app_settings_name, self.app_settings_value) + class RhodeCodeUi(Base): - __tablename__ = 'rhodecode_ui' - __table_args__ = {'useexisting':True} + __tablename__ = "rhodecode_ui" + __table_args__ = {"useexisting": True} ui_id = Column("ui_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - ui_section = Column("ui_section", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - ui_key = Column("ui_key", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - ui_value = Column("ui_value", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) + ui_section = Column( + "ui_section", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + ui_key = Column( + "ui_key", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + ui_value = Column( + "ui_value", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) ui_active = Column("ui_active", Boolean(), nullable=True, unique=None, default=True) class User(Base): - __tablename__ = 'users' - __table_args__ = (UniqueConstraint('username'), UniqueConstraint('email'), {'useexisting':True}) + __tablename__ = "users" + __table_args__ = (UniqueConstraint("username"), UniqueConstraint("email"), {"useexisting": True}) user_id = Column("user_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - username = Column("username", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - password = Column("password", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) + username = Column( + "username", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + password = Column( + "password", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) active = Column("active", Boolean(), nullable=True, unique=None, default=None) admin = Column("admin", Boolean(), nullable=True, unique=None, default=False) - name = Column("name", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - lastname = Column("lastname", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - email = Column("email", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) + name = Column( + "name", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + lastname = Column( + "lastname", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + email = Column( + "email", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) last_login = Column("last_login", DateTime(timezone=False), nullable=True, unique=None, default=None) is_ldap = Column("is_ldap", Boolean(), nullable=False, unique=None, default=False) - user_log = relation('UserLog', cascade='all') - user_perms = relation('UserToPerm', primaryjoin="User.user_id==UserToPerm.user_id", cascade='all') + user_log = relation("UserLog", cascade="all") + user_perms = relation("UserToPerm", primaryjoin="User.user_id==UserToPerm.user_id", cascade="all") - repositories = relation('Repository') - user_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_user_id==User.user_id', cascade='all') + repositories = relation("Repository") + user_followers = relation("UserFollowing", primaryjoin="UserFollowing.follows_user_id==User.user_id", cascade="all") @property def full_contact(self): - return '%s %s <%s>' % (self.name, self.lastname, self.email) + return "%s %s <%s>" % (self.name, self.lastname, self.email) def __repr__(self): return "" % (self.user_id, self.username) @@ -74,119 +165,224 @@ class User(Base): self.last_login = datetime.datetime.now() session.add(self) session.commit() - log.debug('updated user %s lastlogin', self.username) + log.debug("updated user %s lastlogin", self.username) except (DatabaseError,): session.rollback() class UserLog(Base): - __tablename__ = 'user_logs' - __table_args__ = {'useexisting':True} + __tablename__ = "user_logs" + __table_args__ = {"useexisting": True} user_log_id = Column("user_log_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=None, default=None) - repository_name = Column("repository_name", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - user_ip = Column("user_ip", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - action = Column("action", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + repository_name = Column( + "repository_name", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + user_ip = Column( + "user_ip", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + action = Column( + "action", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) action_date = Column("action_date", DateTime(timezone=False), nullable=True, unique=None, default=None) - user = relation('User') - repository = relation('Repository') + user = relation("User") + repository = relation("Repository") + class Repository(Base): - __tablename__ = 'repositories' - __table_args__ = (UniqueConstraint('repo_name'), {'useexisting':True},) + __tablename__ = "repositories" + __table_args__ = ( + UniqueConstraint("repo_name"), + {"useexisting": True}, + ) repo_id = Column("repo_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repo_name = Column("repo_name", String(length=None, convert_unicode=False, ), nullable=False, unique=True, default=None) - repo_type = Column("repo_type", String(length=None, convert_unicode=False, ), nullable=False, unique=False, default=None) - user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=False, default=None) + repo_name = Column( + "repo_name", + String( + length=None, + convert_unicode=False, + ), + nullable=False, + unique=True, + default=None, + ) + repo_type = Column( + "repo_type", + String( + length=None, + convert_unicode=False, + ), + nullable=False, + unique=False, + default=None, + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=False, default=None) private = Column("private", Boolean(), nullable=True, unique=None, default=None) enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) - description = Column("description", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - fork_id = Column("fork_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=False, default=None) + description = Column( + "description", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + fork_id = Column( + "fork_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=False, default=None + ) - user = relation('User') - fork = relation('Repository', remote_side=repo_id) - repo_to_perm = relation('UserRepoToPerm', cascade='all') - stats = relation('Statistics', cascade='all', uselist=False) - - repo_followers = relation('UserFollowing', primaryjoin='UserFollowing.follows_repo_id==Repository.repo_id', cascade='all') + user = relation("User") + fork = relation("Repository", remote_side=repo_id) + repo_to_perm = relation("UserRepoToPerm", cascade="all") + stats = relation("Statistics", cascade="all", uselist=False) + repo_followers = relation( + "UserFollowing", primaryjoin="UserFollowing.follows_repo_id==Repository.repo_id", cascade="all" + ) def __repr__(self): return "" % (self.repo_id, self.repo_name) + class Permission(Base): - __tablename__ = 'permissions' - __table_args__ = {'useexisting':True} + __tablename__ = "permissions" + __table_args__ = {"useexisting": True} permission_id = Column("permission_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - permission_name = Column("permission_name", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) - permission_longname = Column("permission_longname", String(length=None, convert_unicode=False, ), nullable=True, unique=None, default=None) + permission_name = Column( + "permission_name", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) + permission_longname = Column( + "permission_longname", + String( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) def __repr__(self): return "" % (self.permission_id, self.permission_name) -class UserRepoToPerm(Base): - __tablename__ = 'repo_to_perm' - __table_args__ = (UniqueConstraint('user_id', 'repository_id'), {'useexisting':True}) - repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None) - repository_id = Column("repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=None, default=None) - user = relation('User') - permission = relation('Permission') - repository = relation('Repository') +class UserRepoToPerm(Base): + __tablename__ = "repo_to_perm" + __table_args__ = (UniqueConstraint("user_id", "repository_id"), {"useexisting": True}) + repo_to_perm_id = Column("repo_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) + + user = relation("User") + permission = relation("Permission") + repository = relation("Repository") + class UserToPerm(Base): - __tablename__ = 'user_to_perm' - __table_args__ = (UniqueConstraint('user_id', 'permission_id'), {'useexisting':True}) + __tablename__ = "user_to_perm" + __table_args__ = (UniqueConstraint("user_id", "permission_id"), {"useexisting": True}) user_to_perm_id = Column("user_to_perm_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) - permission_id = Column("permission_id", Integer(), ForeignKey(u'permissions.permission_id'), nullable=False, unique=None, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + permission_id = Column( + "permission_id", Integer(), ForeignKey("permissions.permission_id"), nullable=False, unique=None, default=None + ) + + user = relation("User") + permission = relation("Permission") - user = relation('User') - permission = relation('Permission') class Statistics(Base): - __tablename__ = 'statistics' - __table_args__ = (UniqueConstraint('repository_id'), {'useexisting':True}) + __tablename__ = "statistics" + __table_args__ = (UniqueConstraint("repository_id"), {"useexisting": True}) stat_id = Column("stat_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - repository_id = Column("repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=False, unique=True, default=None) + repository_id = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=True, default=None + ) stat_on_revision = Column("stat_on_revision", Integer(), nullable=False) - commit_activity = Column("commit_activity", LargeBinary(), nullable=False)#JSON data - commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False)#JSON data - languages = Column("languages", LargeBinary(), nullable=False)#JSON data + commit_activity = Column("commit_activity", LargeBinary(), nullable=False) # JSON data + commit_activity_combined = Column("commit_activity_combined", LargeBinary(), nullable=False) # JSON data + languages = Column("languages", LargeBinary(), nullable=False) # JSON data + + repository = relation("Repository", single_parent=True) - repository = relation('Repository', single_parent=True) class UserFollowing(Base): - __tablename__ = 'user_followings' - __table_args__ = (UniqueConstraint('user_id', 'follows_repository_id'), - UniqueConstraint('user_id', 'follows_user_id') - , {'useexisting':True}) + __tablename__ = "user_followings" + __table_args__ = ( + UniqueConstraint("user_id", "follows_repository_id"), + UniqueConstraint("user_id", "follows_user_id"), + {"useexisting": True}, + ) - user_following_id = Column("user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - user_id = Column("user_id", Integer(), ForeignKey(u'users.user_id'), nullable=False, unique=None, default=None) - follows_repo_id = Column("follows_repository_id", Integer(), ForeignKey(u'repositories.repo_id'), nullable=True, unique=None, default=None) - follows_user_id = Column("follows_user_id", Integer(), ForeignKey(u'users.user_id'), nullable=True, unique=None, default=None) + user_following_id = Column( + "user_following_id", Integer(), nullable=False, unique=True, default=None, primary_key=True + ) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=False, unique=None, default=None) + follows_repo_id = Column( + "follows_repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None + ) + follows_user_id = Column( + "follows_user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=None, default=None + ) - user = relation('User', primaryjoin='User.user_id==UserFollowing.user_id') + user = relation("User", primaryjoin="User.user_id==UserFollowing.user_id") - follows_user = relation('User', primaryjoin='User.user_id==UserFollowing.follows_user_id') - follows_repository = relation('Repository') + follows_user = relation("User", primaryjoin="User.user_id==UserFollowing.follows_user_id") + follows_repository = relation("Repository") class CacheInvalidation(Base): - __tablename__ = 'cache_invalidation' - __table_args__ = (UniqueConstraint('cache_key'), {'useexisting':True}) + __tablename__ = "cache_invalidation" + __table_args__ = (UniqueConstraint("cache_key"), {"useexisting": True}) cache_id = Column("cache_id", Integer(), nullable=False, unique=True, default=None, primary_key=True) - cache_key = Column("cache_key", String(length=None, convert_unicode=False), nullable=True, unique=None, default=None) - cache_args = Column("cache_args", String(length=None, convert_unicode=False), nullable=True, unique=None, default=None) + cache_key = Column( + "cache_key", String(length=None, convert_unicode=False), nullable=True, unique=None, default=None + ) + cache_args = Column( + "cache_args", String(length=None, convert_unicode=False), nullable=True, unique=None, default=None + ) cache_active = Column("cache_active", Boolean(), nullable=True, unique=None, default=False) - - def __init__(self, cache_key, cache_args=''): + def __init__(self, cache_key, cache_args=""): self.cache_key = cache_key self.cache_args = cache_args self.cache_active = False @@ -200,6 +396,7 @@ def upgrade(migrate_engine): # to your metadata Base.metadata.create_all(bind=migrate_engine, checkfirst=False) + def downgrade(migrate_engine): # Operations to reverse the above upgrade go here. Base.metadata.drop_all(bind=migrate_engine, checkfirst=False) diff --git a/rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py b/rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py index 4d1ebd7e..d8dd12dc 100644 --- a/rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/002_version_1_1_0.py @@ -14,66 +14,71 @@ log = logging.getLogger(__name__) def upgrade(migrate_engine): - """ Upgrade operations go here. + """Upgrade operations go here. Don't create your own engine; bind migrate_engine to your metadata """ - #========================================================================== + # ========================================================================== # Upgrade of `users` table - #========================================================================== - tblname = 'users' - tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True, - autoload_with=migrate_engine) + # ========================================================================== + tblname = "users" + tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True, autoload_with=migrate_engine) - #ADD is_ldap column - is_ldap = Column("is_ldap", Boolean(), nullable=True, - unique=None, default=False) + # ADD is_ldap column + is_ldap = Column("is_ldap", Boolean(), nullable=True, unique=None, default=False) is_ldap.create(tbl, populate_default=True) is_ldap.alter(nullable=False) - #========================================================================== + # ========================================================================== # Upgrade of `user_logs` table - #========================================================================== + # ========================================================================== - tblname = 'users' - tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True, - autoload_with=migrate_engine) + tblname = "users" + tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True, autoload_with=migrate_engine) - #ADD revision column - revision = Column('revision', TEXT(length=None, convert_unicode=False, - ), - nullable=True, unique=None, default=None) + # ADD revision column + revision = Column( + "revision", + TEXT( + length=None, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) revision.create(tbl) - #========================================================================== + # ========================================================================== # Upgrade of `repositories` table - #========================================================================== - tblname = 'repositories' - tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True, - autoload_with=migrate_engine) + # ========================================================================== + tblname = "repositories" + tbl = Table(tblname, MetaData(bind=migrate_engine), autoload=True, autoload_with=migrate_engine) - #ADD repo_type column# - repo_type = Column("repo_type", String(length=None, convert_unicode=False), - nullable=True, unique=False, default='hg') + # ADD repo_type column# + repo_type = Column( + "repo_type", String(length=None, convert_unicode=False), nullable=True, unique=False, default="hg" + ) repo_type.create(tbl, populate_default=True) - #repo_type.alter(nullable=False) + # repo_type.alter(nullable=False) - #ADD statistics column# - enable_statistics = Column("statistics", Boolean(), nullable=True, - unique=None, default=True) + # ADD statistics column# + enable_statistics = Column("statistics", Boolean(), nullable=True, unique=None, default=True) enable_statistics.create(tbl) - #========================================================================== + # ========================================================================== # Add table `user_followings` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_1_0 import UserFollowing + UserFollowing().__table__.create() - #========================================================================== + # ========================================================================== # Add table `cache_invalidation` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_1_0 import CacheInvalidation + CacheInvalidation().__table__.create() return diff --git a/rhodecode/lib/dbmigrate/versions/003_version_1_2_0.py b/rhodecode/lib/dbmigrate/versions/003_version_1_2_0.py index 307378a1..1e115524 100644 --- a/rhodecode/lib/dbmigrate/versions/003_version_1_2_0.py +++ b/rhodecode/lib/dbmigrate/versions/003_version_1_2_0.py @@ -15,98 +15,123 @@ log = logging.getLogger(__name__) def upgrade(migrate_engine): - """ Upgrade operations go here. + """Upgrade operations go here. Don't create your own engine; bind migrate_engine to your metadata """ - #========================================================================== + # ========================================================================== # Add table `groups`` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import Group as Group + Group().__table__.create() - #========================================================================== + # ========================================================================== # Add table `group_to_perm` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserRepoGroupToPerm + UserRepoGroupToPerm().__table__.create() - #========================================================================== + # ========================================================================== # Add table `users_groups` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroup + UserGroup().__table__.create() - #========================================================================== + # ========================================================================== # Add table `users_groups_members` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroupMember + UserGroupMember().__table__.create() - #========================================================================== + # ========================================================================== # Add table `users_group_repo_to_perm` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroupRepoToPerm + UserGroupRepoToPerm().__table__.create() - #========================================================================== + # ========================================================================== # Add table `users_group_to_perm` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserGroupToPerm + UserGroupToPerm().__table__.create() - #========================================================================== + # ========================================================================== # Upgrade of `users` table - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import User - #add column - ldap_dn = Column("ldap_dn", String(length=255, convert_unicode=False, ), nullable=True, unique=None, default=None) + # add column + ldap_dn = Column( + "ldap_dn", + String( + length=255, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) ldap_dn.create(User().__table__) - api_key = Column("api_key", String(length=255, convert_unicode=False, ), nullable=True, unique=None, default=None) + api_key = Column( + "api_key", + String( + length=255, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) api_key.create(User().__table__) - #remove old column + # remove old column is_ldap = Column("is_ldap", Boolean(), nullable=False, unique=None, default=False) is_ldap.drop(User().__table__) - #========================================================================== + # ========================================================================== # Upgrade of `repositories` table - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import Repository - #ADD clone_uri column# + # ADD clone_uri column# - clone_uri = Column("clone_uri", String(length=255, convert_unicode=False), - nullable=True, unique=False, default=None) + clone_uri = Column( + "clone_uri", String(length=255, convert_unicode=False), nullable=True, unique=False, default=None + ) clone_uri.create(Repository().__table__) - #ADD downloads column# + # ADD downloads column# enable_downloads = Column("downloads", Boolean(), nullable=True, unique=None, default=True) enable_downloads.create(Repository().__table__) - #ADD column created_on - created_on = Column('created_on', DateTime(timezone=False), nullable=True, - unique=None, default=datetime.datetime.now) + # ADD column created_on + created_on = Column( + "created_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) created_on.create(Repository().__table__) - #ADD group_id column# - group_id = Column("group_id", Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=False, default=None) + # ADD group_id column# + group_id = Column("group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=False, default=None) group_id.create(Repository().__table__) - #========================================================================== + # ========================================================================== # Upgrade of `user_followings` table - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_2_0 import UserFollowing - follows_from = Column('follows_from', DateTime(timezone=False), - nullable=True, unique=None, - default=datetime.datetime.now) + follows_from = Column( + "follows_from", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) follows_from.create(UserFollowing().__table__) return diff --git a/rhodecode/lib/dbmigrate/versions/004_version_1_3_0.py b/rhodecode/lib/dbmigrate/versions/004_version_1_3_0.py index 3c46146b..a79fc0e0 100644 --- a/rhodecode/lib/dbmigrate/versions/004_version_1_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/004_version_1_3_0.py @@ -15,56 +15,62 @@ log = logging.getLogger(__name__) def upgrade(migrate_engine): - """ Upgrade operations go here. + """Upgrade operations go here. Don't create your own engine; bind migrate_engine to your metadata """ - #========================================================================== + # ========================================================================== # Add table `users_group_repo_group_to_perm` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserGroupRepoGroupToPerm + UserGroupRepoGroupToPerm().__table__.create() - #========================================================================== + # ========================================================================== # Add table `changeset_comments` - #========================================================================== - from rhodecode.lib.dbmigrate.schema.db_1_3_0 import ChangesetComment + # ========================================================================== + from rhodecode.lib.dbmigrate.schema.db_1_3_0 import ChangesetComment + ChangesetComment().__table__.create() - #========================================================================== + # ========================================================================== # Add table `notifications` - #========================================================================== - from rhodecode.lib.dbmigrate.schema.db_1_3_0 import Notification + # ========================================================================== + from rhodecode.lib.dbmigrate.schema.db_1_3_0 import Notification + Notification().__table__.create() - #========================================================================== + # ========================================================================== # Add table `user_to_notification` - #========================================================================== - from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserNotification + # ========================================================================== + from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserNotification + UserNotification().__table__.create() - #========================================================================== + # ========================================================================== # Add unique to table `users_group_to_perm` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserGroupToPerm + tbl = UserGroupToPerm().__table__ - cons = UniqueConstraint('users_group_id', 'permission_id', table=tbl) + cons = UniqueConstraint("users_group_id", "permission_id", table=tbl) cons.create() - #========================================================================== + # ========================================================================== # Fix unique constrain on table `user_logs` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserLog + tbl = UserLog().__table__ - col = Column("repository_id", Integer(), ForeignKey('repositories.repo_id'), - nullable=False, unique=None, default=None) + col = Column( + "repository_id", Integer(), ForeignKey("repositories.repo_id"), nullable=False, unique=None, default=None + ) col.alter(nullable=True, table=tbl) - #========================================================================== + # ========================================================================== # Rename table `group_to_perm` to `user_repo_group_to_perm` - #========================================================================== - tbl = Table('group_to_perm', MetaData(bind=migrate_engine), autoload=True, - autoload_with=migrate_engine) - tbl.rename('user_repo_group_to_perm') + # ========================================================================== + tbl = Table("group_to_perm", MetaData(bind=migrate_engine), autoload=True, autoload_with=migrate_engine) + tbl.rename("user_repo_group_to_perm") return diff --git a/rhodecode/lib/dbmigrate/versions/005_version_1_3_0.py b/rhodecode/lib/dbmigrate/versions/005_version_1_3_0.py index d4056f7b..97c0a22c 100644 --- a/rhodecode/lib/dbmigrate/versions/005_version_1_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/005_version_1_3_0.py @@ -15,22 +15,23 @@ log = logging.getLogger(__name__) def upgrade(migrate_engine): - """ Upgrade operations go here. + """Upgrade operations go here. Don't create your own engine; bind migrate_engine to your metadata """ - #========================================================================== + # ========================================================================== # Change unique constraints of table `repo_to_perm` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserRepoToPerm + tbl = UserRepoToPerm().__table__ - new_cons = UniqueConstraint('user_id', 'repository_id', 'permission_id', table=tbl) + new_cons = UniqueConstraint("user_id", "repository_id", "permission_id", table=tbl) new_cons.create() old_cons = None - if migrate_engine.name in ['mysql']: - old_cons = UniqueConstraint('user_id', 'repository_id', table=tbl, name="user_id") - elif migrate_engine.name in ['postgresql']: - old_cons = UniqueConstraint('user_id', 'repository_id', table=tbl) + if migrate_engine.name in ["mysql"]: + old_cons = UniqueConstraint("user_id", "repository_id", table=tbl, name="user_id") + elif migrate_engine.name in ["postgresql"]: + old_cons = UniqueConstraint("user_id", "repository_id", table=tbl) else: # sqlite doesn't support dropping constraints... print("""Please manually drop UniqueConstraint('user_id', 'repository_id')""") @@ -41,24 +42,26 @@ def upgrade(migrate_engine): except Exception as e: # we don't care if this fails really... better to pass migration than # leave this in intermidiate state - print('Failed to remove Unique for user_id, repository_id reason %s' % e) + print("Failed to remove Unique for user_id, repository_id reason %s" % e) - - #========================================================================== + # ========================================================================== # fix uniques of table `user_repo_group_to_perm` - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserRepoGroupToPerm + tbl = UserRepoGroupToPerm().__table__ - new_cons = UniqueConstraint('group_id', 'permission_id', 'user_id', table=tbl) + new_cons = UniqueConstraint("group_id", "permission_id", "user_id", table=tbl) new_cons.create() old_cons = None # fix uniqueConstraints - if migrate_engine.name in ['mysql']: - #mysql is givinig troubles here... - old_cons = UniqueConstraint('group_id', 'permission_id', table=tbl, name="group_id") - elif migrate_engine.name in ['postgresql']: - old_cons = UniqueConstraint('group_id', 'permission_id', table=tbl, name='group_to_perm_group_id_permission_id_key') + if migrate_engine.name in ["mysql"]: + # mysql is givinig troubles here... + old_cons = UniqueConstraint("group_id", "permission_id", table=tbl, name="group_id") + elif migrate_engine.name in ["postgresql"]: + old_cons = UniqueConstraint( + "group_id", "permission_id", table=tbl, name="group_to_perm_group_id_permission_id_key" + ) else: # sqlite doesn't support dropping constraints... print("""Please manually drop UniqueConstraint('group_id', 'permission_id')""") @@ -69,7 +72,7 @@ def upgrade(migrate_engine): except Exception as e: # we don't care if this fails really... better to pass migration than # leave this in intermidiate state - print('Failed to remove Unique for user_id, repository_id reason %s' % e) + print("Failed to remove Unique for user_id, repository_id reason %s" % e) return diff --git a/rhodecode/lib/dbmigrate/versions/006_version_1_4_0.py b/rhodecode/lib/dbmigrate/versions/006_version_1_4_0.py index 06c6d5a5..d842c24c 100644 --- a/rhodecode/lib/dbmigrate/versions/006_version_1_4_0.py +++ b/rhodecode/lib/dbmigrate/versions/006_version_1_4_0.py @@ -23,151 +23,156 @@ def upgrade(migrate_engine): Don't create your own engine; bind migrate_engine to your metadata """ - #========================================================================== + # ========================================================================== # USEREMAILMAP - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_4_0 import UserEmailMap + tbl = UserEmailMap.__table__ tbl.create() - #========================================================================== + # ========================================================================== # PULL REQUEST - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_4_0 import PullRequest + tbl = PullRequest.__table__ tbl.create() - #========================================================================== + # ========================================================================== # PULL REQUEST REVIEWERS - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_4_0 import PullRequestReviewers + tbl = PullRequestReviewers.__table__ tbl.create() - #========================================================================== + # ========================================================================== # CHANGESET STATUS - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_4_0 import ChangesetStatus + tbl = ChangesetStatus.__table__ tbl.create() _reset_base(migrate_engine) - #========================================================================== + # ========================================================================== # USERS TABLE - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import User + tbl = User.__table__ # change column name -> firstname col = User.__table__.columns.name - col.alter(index=Index('u_username_idx', 'username')) - col.alter(index=Index('u_email_idx', 'email')) + col.alter(index=Index("u_username_idx", "username")) + col.alter(index=Index("u_email_idx", "email")) col.alter(name="firstname", table=tbl) # add inherit_default_permission column - inherit_default_permissions = Column("inherit_default_permissions", - Boolean(), nullable=True, unique=None, - default=True) + inherit_default_permissions = Column( + "inherit_default_permissions", Boolean(), nullable=True, unique=None, default=True + ) inherit_default_permissions.create(table=tbl) inherit_default_permissions.alter(nullable=False, default=True, table=tbl) - #========================================================================== + # ========================================================================== # USERS GROUP TABLE - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import UserGroup + tbl = UserGroup.__table__ # add inherit_default_permission column gr_inherit_default_permissions = Column( - "users_group_inherit_default_permissions", - Boolean(), nullable=True, unique=None, - default=True) + "users_group_inherit_default_permissions", Boolean(), nullable=True, unique=None, default=True + ) gr_inherit_default_permissions.create(table=tbl) gr_inherit_default_permissions.alter(nullable=False, default=True, table=tbl) - #========================================================================== + # ========================================================================== # REPOSITORIES - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import Repository + tbl = Repository.__table__ # add enable locking column - enable_locking = Column("enable_locking", Boolean(), nullable=True, - unique=None, default=False) + enable_locking = Column("enable_locking", Boolean(), nullable=True, unique=None, default=False) enable_locking.create(table=tbl) enable_locking.alter(nullable=False, default=False, table=tbl) # add locked column - _locked = Column("locked", String(255), nullable=True, unique=False, - default=None) + _locked = Column("locked", String(255), nullable=True, unique=False, default=None) _locked.create(table=tbl) - #add langing revision column - landing_rev = Column("landing_revision", String(255), nullable=True, - unique=False, default='tip') + # add langing revision column + landing_rev = Column("landing_revision", String(255), nullable=True, unique=False, default="tip") landing_rev.create(table=tbl) - landing_rev.alter(nullable=False, default='tip', table=tbl) + landing_rev.alter(nullable=False, default="tip", table=tbl) - #========================================================================== + # ========================================================================== # GROUPS - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import RepoGroup + tbl = RepoGroup.__table__ # add enable locking column - enable_locking = Column("enable_locking", Boolean(), nullable=True, - unique=None, default=False) + enable_locking = Column("enable_locking", Boolean(), nullable=True, unique=None, default=False) enable_locking.create(table=tbl) enable_locking.alter(nullable=False, default=False) - #========================================================================== + # ========================================================================== # CACHE INVALIDATION - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import CacheInvalidation + tbl = CacheInvalidation.__table__ # add INDEX for cache keys col = CacheInvalidation.__table__.columns.cache_key - col.alter(index=Index('key_idx', 'cache_key')) + col.alter(index=Index("key_idx", "cache_key")) - #========================================================================== + # ========================================================================== # NOTIFICATION - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import Notification + tbl = Notification.__table__ # add index for notification type col = Notification.__table__.columns.type - col.alter(index=Index('notification_type_idx', 'type'),) + col.alter( + index=Index("notification_type_idx", "type"), + ) - #========================================================================== + # ========================================================================== # CHANGESET_COMMENTS - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_3_0 import ChangesetComment tbl = ChangesetComment.__table__ col = ChangesetComment.__table__.columns.revision # add index for revisions - col.alter(index=Index('cc_revision_idx', 'revision'),) + col.alter( + index=Index("cc_revision_idx", "revision"), + ) # add hl_lines column - hl_lines = Column('hl_lines', Unicode(512), nullable=True) + hl_lines = Column("hl_lines", Unicode(512), nullable=True) hl_lines.create(table=tbl) # add created_on column - created_on = Column('created_on', DateTime(timezone=False), nullable=True, - default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=True, default=datetime.datetime.now) created_on.create(table=tbl) created_on.alter(nullable=False, default=datetime.datetime.now) - modified_at = Column('modified_at', DateTime(timezone=False), nullable=False, - default=datetime.datetime.now) + modified_at = Column("modified_at", DateTime(timezone=False), nullable=False, default=datetime.datetime.now) modified_at.alter(type=DateTime(timezone=False), table=tbl) # add FK to pull_request - pull_request_id = Column("pull_request_id", Integer(), - ForeignKey('pull_requests.pull_request_id'), - nullable=True) + pull_request_id = Column("pull_request_id", Integer(), ForeignKey("pull_requests.pull_request_id"), nullable=True) pull_request_id.create(table=tbl) _reset_base(migrate_engine) diff --git a/rhodecode/lib/dbmigrate/versions/007_version_1_4_0.py b/rhodecode/lib/dbmigrate/versions/007_version_1_4_0.py index fb167cd7..4d2aec2a 100644 --- a/rhodecode/lib/dbmigrate/versions/007_version_1_4_0.py +++ b/rhodecode/lib/dbmigrate/versions/007_version_1_4_0.py @@ -22,26 +22,25 @@ def upgrade(migrate_engine): Don't create your own engine; bind migrate_engine to your metadata """ - #========================================================================== + # ========================================================================== # CHANGESET_COMMENTS - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_4_0 import ChangesetComment + tbl_name = ChangesetComment.__tablename__ - tbl = Table(tbl_name, - MetaData(bind=migrate_engine), autoload=True, - autoload_with=migrate_engine) + tbl = Table(tbl_name, MetaData(bind=migrate_engine), autoload=True, autoload_with=migrate_engine) col = tbl.columns.revision # remove nullability from revision field col.alter(nullable=True) - #========================================================================== + # ========================================================================== # REPOSITORY - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_4_0 import Repository + tbl = Repository.__table__ - updated_on = Column('updated_on', DateTime(timezone=False), - nullable=True, unique=None) + updated_on = Column("updated_on", DateTime(timezone=False), nullable=True, unique=None) # create created on column for future lightweight main page updated_on.create(table=tbl) diff --git a/rhodecode/lib/dbmigrate/versions/008_version_1_5_0.py b/rhodecode/lib/dbmigrate/versions/008_version_1_5_0.py index 1c1366e9..440099fc 100644 --- a/rhodecode/lib/dbmigrate/versions/008_version_1_5_0.py +++ b/rhodecode/lib/dbmigrate/versions/008_version_1_5_0.py @@ -24,21 +24,23 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_1_5_0 - #========================================================================== + # ========================================================================== # USER LOGS - #========================================================================== + # ========================================================================== tbl = db_1_5_0.UserLog.__table__ - username = Column("username", String(255, convert_unicode=False), - nullable=True, unique=None, default=None) + username = Column("username", String(255, convert_unicode=False), nullable=True, unique=None, default=None) # create username column username.create(table=tbl) _Session = meta.Session() # after adding that column fix all usernames - users_log = _Session.query(db_1_5_0.UserLog)\ - .options(joinedload(db_1_5_0.UserLog.user))\ - .options(joinedload(db_1_5_0.UserLog.repository)).all() + users_log = ( + _Session.query(db_1_5_0.UserLog) + .options(joinedload(db_1_5_0.UserLog.user)) + .options(joinedload(db_1_5_0.UserLog.repository)) + .all() + ) for entry in users_log: entry.username = entry.user.username @@ -47,9 +49,7 @@ def upgrade(migrate_engine): # alter username to not null tbl_name = db_1_5_0.UserLog.__tablename__ - tbl = Table(tbl_name, - MetaData(bind=migrate_engine), autoload=True, - autoload_with=migrate_engine) + tbl = Table(tbl_name, MetaData(bind=migrate_engine), autoload=True, autoload_with=migrate_engine) col = tbl.columns.username # remove nullability from revision field @@ -80,14 +80,14 @@ def fixups(models, _SESSION): new_perm = models.Permission() new_perm.permission_name = p[0] new_perm.permission_longname = p[0] # translation err with p[1] - print('Creating new permission %s' % p[0]) + print("Creating new permission %s" % p[0]) _SESSION().add(new_perm) _SESSION().commit() # ** populate default permissions ** # - user = models.User.query().filter(models.User.username == 'default').scalar() + user = models.User.query().filter(models.User.username == "default").scalar() def _make_perm(perm): new_perm = models.UserToPerm() @@ -96,13 +96,12 @@ def fixups(models, _SESSION): return new_perm def _get_group(perm_name): - return '.'.join(perm_name.split('.')[:1]) + return ".".join(perm_name.split(".")[:1]) perms = models.UserToPerm.query().filter(models.UserToPerm.user == user).all() - defined_perms_groups = list(map( - _get_group, (x.permission.permission_name for x in perms))) + defined_perms_groups = list(map(_get_group, (x.permission.permission_name for x in perms))) perms_show = [p.__dict__ for p in perms] - log.debug('GOT ALREADY DEFINED:%s', perms_show) + log.debug("GOT ALREADY DEFINED:%s", perms_show) DEFAULT_PERMS = models.Permission.DEFAULT_USER_PERMISSIONS # for every default permission that needs to be created, we check if @@ -110,23 +109,23 @@ def fixups(models, _SESSION): for perm_name in DEFAULT_PERMS: gr = _get_group(perm_name) if gr not in defined_perms_groups: - log.debug('GR:%s not found, creating permission %s', gr, perm_name) + log.debug("GR:%s not found, creating permission %s", gr, perm_name) new_perm = _make_perm(perm_name) _SESSION().add(new_perm) _SESSION().commit() # ** create default options ** # - #=============================== + # =============================== skip_existing = True for k, v in [ - ('default_repo_enable_locking', False), - ('default_repo_enable_downloads', False), - ('default_repo_enable_statistics', False), - ('default_repo_private', False), - ('default_repo_type', 'hg')]: - + ("default_repo_enable_locking", False), + ("default_repo_enable_downloads", False), + ("default_repo_enable_statistics", False), + ("default_repo_private", False), + ("default_repo_type", "hg"), + ]: if skip_existing and get_by_name(models.RhodeCodeSetting, k) is not None: - log.debug('Skipping option %s', k) + log.debug("Skipping option %s", k) continue setting = models.RhodeCodeSetting(k, v) _SESSION().add(setting) diff --git a/rhodecode/lib/dbmigrate/versions/009_version_1_5_1.py b/rhodecode/lib/dbmigrate/versions/009_version_1_5_1.py index 44ef4266..cc36319e 100644 --- a/rhodecode/lib/dbmigrate/versions/009_version_1_5_1.py +++ b/rhodecode/lib/dbmigrate/versions/009_version_1_5_1.py @@ -23,6 +23,7 @@ def upgrade(migrate_engine): """ pass + def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine diff --git a/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py b/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py index e53cdd4c..69607f87 100644 --- a/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py +++ b/rhodecode/lib/dbmigrate/versions/010_version_1_5_2.py @@ -24,15 +24,16 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_1_5_2 - #========================================================================== + + # ========================================================================== # USER LOGS - #========================================================================== + # ========================================================================== tbl = db_1_5_2.UserIpMap.__table__ tbl.create() - #========================================================================== + # ========================================================================== # REPOSITORIES - #========================================================================== + # ========================================================================== tbl = db_1_5_2.Repository.__table__ changeset_cache = Column("changeset_cache", LargeBinary(), nullable=True) # create username column @@ -42,5 +43,3 @@ def upgrade(migrate_engine): def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine - - diff --git a/rhodecode/lib/dbmigrate/versions/011_version_1_6_0.py b/rhodecode/lib/dbmigrate/versions/011_version_1_6_0.py index 02a045aa..bef90238 100644 --- a/rhodecode/lib/dbmigrate/versions/011_version_1_6_0.py +++ b/rhodecode/lib/dbmigrate/versions/011_version_1_6_0.py @@ -25,9 +25,9 @@ def upgrade(migrate_engine): _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_1_6_0 - #========================================================================== + # ========================================================================== # USER LOGS - #========================================================================== + # ========================================================================== tbl = db_1_6_0.RepositoryField.__table__ tbl.create() @@ -41,7 +41,7 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Upgrading repositories Caches') + notify("Upgrading repositories Caches") repositories = models.Repository.getAll() for repo in repositories: print(repo) diff --git a/rhodecode/lib/dbmigrate/versions/012_version_1_7_0.py b/rhodecode/lib/dbmigrate/versions/012_version_1_7_0.py index 2d47a9c4..7418e423 100644 --- a/rhodecode/lib/dbmigrate/versions/012_version_1_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/012_version_1_7_0.py @@ -25,39 +25,37 @@ def upgrade(migrate_engine): _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_1_7_0 - #========================================================================== + # ========================================================================== # UserUserGroupToPerm - #========================================================================== + # ========================================================================== tbl = db_1_7_0.UserUserGroupToPerm.__table__ tbl.create() - #========================================================================== + # ========================================================================== # UserGroupUserGroupToPerm - #========================================================================== + # ========================================================================== tbl = db_1_7_0.UserGroupUserGroupToPerm.__table__ tbl.create() - #========================================================================== + # ========================================================================== # Gist - #========================================================================== + # ========================================================================== tbl = db_1_7_0.Gist.__table__ tbl.create() - #========================================================================== + # ========================================================================== # UserGroup - #========================================================================== + # ========================================================================== tbl = db_1_7_0.UserGroup.__table__ - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), - nullable=True, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=False, default=None) # create username column user_id.create(table=tbl) - #========================================================================== + # ========================================================================== # RepoGroup - #========================================================================== + # ========================================================================== tbl = db_1_7_0.RepoGroup.__table__ - user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), - nullable=True, unique=False, default=None) + user_id = Column("user_id", Integer(), ForeignKey("users.user_id"), nullable=True, unique=False, default=None) # create username column user_id.create(table=tbl) @@ -76,7 +74,7 @@ def get_by_key(cls, key): def fixups(models, _SESSION): # ** create default permissions ** # - #===================================== + # ===================================== for p in models.Permission.PERMS: if not get_by_key(models.Permission, p[0]): new_perm = models.Permission() @@ -87,9 +85,9 @@ def fixups(models, _SESSION): _SESSION().commit() # ** populate default permissions ** # - #===================================== + # ===================================== - user = models.User.query().filter(models.User.username == 'default').scalar() + user = models.User.query().filter(models.User.username == "default").scalar() def _make_perm(perm): new_perm = models.UserToPerm() @@ -98,11 +96,11 @@ def fixups(models, _SESSION): return new_perm def _get_group(perm_name): - return '.'.join(perm_name.split('.')[:1]) + return ".".join(perm_name.split(".")[:1]) perms = models.UserToPerm.query().filter(models.UserToPerm.user == user).all() defined_perms_groups = list(map(_get_group, (x.permission.permission_name for x in perms))) - log.debug('GOT ALREADY DEFINED:%s', perms) + log.debug("GOT ALREADY DEFINED:%s", perms) DEFAULT_PERMS = models.Permission.DEFAULT_USER_PERMISSIONS # for every default permission that needs to be created, we check if @@ -110,19 +108,19 @@ def fixups(models, _SESSION): for perm_name in DEFAULT_PERMS: gr = _get_group(perm_name) if gr not in defined_perms_groups: - log.debug('GR:%s not found, creating permission %s', gr, perm_name) + log.debug("GR:%s not found, creating permission %s", gr, perm_name) new_perm = _make_perm(perm_name) _SESSION().add(new_perm) _SESSION().commit() - #fix all usergroups + # fix all usergroups def _create_default_perms(user_group): # create default permission - default_perm = 'usergroup.read' + default_perm = "usergroup.read" def_user = models.User.get_default_user() for p in def_user.user_perms: - if p.permission.permission_name.startswith('usergroup.'): + if p.permission.permission_name.startswith("usergroup."): default_perm = p.permission.permission_name break diff --git a/rhodecode/lib/dbmigrate/versions/013_version_1_7_0.py b/rhodecode/lib/dbmigrate/versions/013_version_1_7_0.py index 3e86ac02..71a0dc1c 100644 --- a/rhodecode/lib/dbmigrate/versions/013_version_1_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/013_version_1_7_0.py @@ -24,19 +24,20 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) - - #========================================================================== + # ========================================================================== # UserGroup - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_7_0 import UserGroup + tbl = UserGroup.__table__ user_id = tbl.columns.user_id user_id.alter(nullable=False) - #========================================================================== + # ========================================================================== # RepoGroup - #========================================================================== + # ========================================================================== from rhodecode.lib.dbmigrate.schema.db_1_7_0 import RepoGroup + tbl = RepoGroup.__table__ user_id = tbl.columns.user_id user_id.alter(nullable=False) diff --git a/rhodecode/lib/dbmigrate/versions/014_version_1_7_1.py b/rhodecode/lib/dbmigrate/versions/014_version_1_7_1.py index 7aaa1de7..488daa38 100644 --- a/rhodecode/lib/dbmigrate/versions/014_version_1_7_1.py +++ b/rhodecode/lib/dbmigrate/versions/014_version_1_7_1.py @@ -25,9 +25,9 @@ def upgrade(migrate_engine): _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_1_7_0 - #========================================================================== + # ========================================================================== # Gist - #========================================================================== + # ========================================================================== tbl = db_1_7_0.Gist.__table__ user_id = tbl.columns.gist_expires user_id.alter(type=Float(53)) diff --git a/rhodecode/lib/dbmigrate/versions/015_version_1_8_0.py b/rhodecode/lib/dbmigrate/versions/015_version_1_8_0.py index e51fd99e..af1e7c2c 100644 --- a/rhodecode/lib/dbmigrate/versions/015_version_1_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/015_version_1_8_0.py @@ -28,10 +28,11 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_1_8_0 + tbl = db_1_8_0.RhodeCodeSetting.__table__ - app_settings_type = Column("app_settings_type", - String(255, convert_unicode=False), - nullable=True, unique=None, default=None) + app_settings_type = Column( + "app_settings_type", String(255, convert_unicode=False), nullable=True, unique=None, default=None + ) app_settings_type.create(table=tbl) # issue fixups @@ -44,27 +45,25 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Fixing default options now...') + notify("Fixing default options now...") settings = [ - #general - ('realm', '', 'unicode'), - ('title', '', 'unicode'), - ('ga_code', '', 'unicode'), - ('show_public_icon', False, 'bool'), - ('show_private_icon', True, 'bool'), - ('stylify_metatags', True, 'bool'), - + # general + ("realm", "", "unicode"), + ("title", "", "unicode"), + ("ga_code", "", "unicode"), + ("show_public_icon", False, "bool"), + ("show_private_icon", True, "bool"), + ("stylify_metatags", True, "bool"), # defaults - ('default_repo_enable_locking', False, 'bool'), - ('default_repo_enable_downloads', False, 'bool'), - ('default_repo_enable_statistics', False, 'bool'), - ('default_repo_private', False, 'bool'), - ('default_repo_type', 'hg', 'unicode'), - - #other - ('dashboard_items', 100, 'int'), - ('show_version', True, 'bool') + ("default_repo_enable_locking", False, "bool"), + ("default_repo_enable_downloads", False, "bool"), + ("default_repo_enable_statistics", False, "bool"), + ("default_repo_private", False, "bool"), + ("default_repo_type", "hg", "unicode"), + # other + ("dashboard_items", 100, "int"), + ("show_version", True, "bool"), ] for name, default, type_ in settings: @@ -74,9 +73,9 @@ def fixups(models, _SESSION): setting = models.RhodeCodeSetting(name, default, type_) # fix certain key to new defaults - if name in ['title', 'show_public_icon']: + if name in ["title", "show_public_icon"]: # change title if it's only the default - if name == 'title' and setting.app_settings_value == 'RhodeCode': + if name == "title" and setting.app_settings_value == "RhodeCode": setting.app_settings_value = default else: setting.app_settings_value = default diff --git a/rhodecode/lib/dbmigrate/versions/016_version_2_0_0.py b/rhodecode/lib/dbmigrate/versions/016_version_2_0_0.py index 60eeb251..cba3e4ac 100644 --- a/rhodecode/lib/dbmigrate/versions/016_version_2_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/016_version_2_0_0.py @@ -24,19 +24,25 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_2_0_0 + tbl = db_2_0_0.User.__table__ - extern_type = Column("extern_type", - String(255, convert_unicode=False, ), - nullable=True, unique=None, default=None) + extern_type = Column( + "extern_type", + String( + 255, + convert_unicode=False, + ), + nullable=True, + unique=None, + default=None, + ) extern_type.create(table=tbl) - extern_name = Column("extern_name", String(255, convert_unicode=False), - nullable=True, unique=None, default=None) + extern_name = Column("extern_name", String(255, convert_unicode=False), nullable=True, unique=None, default=None) extern_name.create(table=tbl) - created_on = Column('created_on', DateTime(timezone=False), - nullable=True, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=True, default=datetime.datetime.now) created_on.create(table=tbl) # issue fixups @@ -49,21 +55,21 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Fixing default created on') + notify("Fixing default created on") for usr in models.User.get_all(): usr.created_on = datetime.datetime.now() _SESSION().add(usr) _SESSION().commit() - notify('Migrating LDAP attribute to extern') + notify("Migrating LDAP attribute to extern") for usr in models.User.get_all(): ldap_dn = usr.ldap_dn if ldap_dn: usr.extern_name = ldap_dn - usr.extern_type = 'ldap' + usr.extern_type = "ldap" else: - usr.extern_name = 'rhodecode' - usr.extern_type = 'rhodecode' + usr.extern_name = "rhodecode" + usr.extern_type = "rhodecode" _SESSION().add(usr) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/017_version_2_0_0.py b/rhodecode/lib/dbmigrate/versions/017_version_2_0_0.py index e1273836..37955db9 100644 --- a/rhodecode/lib/dbmigrate/versions/017_version_2_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/017_version_2_0_0.py @@ -24,15 +24,15 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_2_0_0 + tbl = db_2_0_0.UserGroup.__table__ - user_group_description = Column("user_group_description", - String(10000, convert_unicode=False), - nullable=True, unique=None, default=None) + user_group_description = Column( + "user_group_description", String(10000, convert_unicode=False), nullable=True, unique=None, default=None + ) user_group_description.create(table=tbl) - created_on = Column('created_on', DateTime(timezone=False), - nullable=True, default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=True, default=datetime.datetime.now) created_on.create(table=tbl) # issue fixups @@ -45,7 +45,7 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Fixing default created on') + notify("Fixing default created on") for gr in models.UserGroup.get_all(): gr.created_on = datetime.datetime.now() diff --git a/rhodecode/lib/dbmigrate/versions/018_version_2_0_0.py b/rhodecode/lib/dbmigrate/versions/018_version_2_0_0.py index 7f08d044..e3b9e61d 100644 --- a/rhodecode/lib/dbmigrate/versions/018_version_2_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/018_version_2_0_0.py @@ -40,18 +40,18 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Fixing default auth modules') - plugins = 'rhodecode.lib.auth_modules.auth_rhodecode' + notify("Fixing default auth modules") + plugins = "rhodecode.lib.auth_modules.auth_rhodecode" opts = [] - ldap_enabled = str2bool(getattr( - get_by_name(models.RhodeCodeSetting, 'ldap_active'), - 'app_settings_value', False)) + ldap_enabled = str2bool(getattr(get_by_name(models.RhodeCodeSetting, "ldap_active"), "app_settings_value", False)) if ldap_enabled: - plugins += ',rhodecode.lib.auth_modules.auth_ldap' - opts.append(('auth_ldap_enabled', 'True', 'bool')) + plugins += ",rhodecode.lib.auth_modules.auth_ldap" + opts.append(("auth_ldap_enabled", "True", "bool")) - opts.append(('auth_plugins', plugins, 'list'),) - opts.append(('auth_rhodecode_enabled', 'True', 'bool')) + opts.append( + ("auth_plugins", plugins, "list"), + ) + opts.append(("auth_rhodecode_enabled", "True", "bool")) for name, default, type_ in opts: setting = get_by_name(models.RhodeCodeSetting, name) @@ -62,17 +62,26 @@ def fixups(models, _SESSION): _SESSION().add(setting) _SESSION().commit() - #copy over the LDAP settings - old_ldap = [('ldap_active', 'false', 'bool'), ('ldap_host', '', 'unicode'), - ('ldap_port', '389', 'int'), ('ldap_tls_kind', 'PLAIN', 'unicode'), - ('ldap_tls_reqcert', '', 'unicode'), ('ldap_dn_user', '', 'unicode'), - ('ldap_dn_pass', '', 'unicode'), ('ldap_base_dn', '', 'unicode'), - ('ldap_filter', '', 'unicode'), ('ldap_search_scope', '', 'unicode'), - ('ldap_attr_login', '', 'unicode'), ('ldap_attr_firstname', '', 'unicode'), - ('ldap_attr_lastname', '', 'unicode'), ('ldap_attr_email', '', 'unicode')] + # copy over the LDAP settings + old_ldap = [ + ("ldap_active", "false", "bool"), + ("ldap_host", "", "unicode"), + ("ldap_port", "389", "int"), + ("ldap_tls_kind", "PLAIN", "unicode"), + ("ldap_tls_reqcert", "", "unicode"), + ("ldap_dn_user", "", "unicode"), + ("ldap_dn_pass", "", "unicode"), + ("ldap_base_dn", "", "unicode"), + ("ldap_filter", "", "unicode"), + ("ldap_search_scope", "", "unicode"), + ("ldap_attr_login", "", "unicode"), + ("ldap_attr_firstname", "", "unicode"), + ("ldap_attr_lastname", "", "unicode"), + ("ldap_attr_email", "", "unicode"), + ] for k, v, t in old_ldap: old_setting = get_by_name(models.RhodeCodeSetting, k) - name = 'auth_%s' % k + name = "auth_%s" % k setting = get_by_name(models.RhodeCodeSetting, name) if not setting: # if we don't have this option create it diff --git a/rhodecode/lib/dbmigrate/versions/019_version_2_0_0.py b/rhodecode/lib/dbmigrate/versions/019_version_2_0_0.py index e70ff5bb..c0d1671d 100644 --- a/rhodecode/lib/dbmigrate/versions/019_version_2_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/019_version_2_0_0.py @@ -25,6 +25,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_2_0_0 + tbl = db_2_0_0.RhodeCodeSetting.__table__ settings_value = tbl.columns.app_settings_value settings_value.alter(type=String(4096)) diff --git a/rhodecode/lib/dbmigrate/versions/020_version_2_0_1.py b/rhodecode/lib/dbmigrate/versions/020_version_2_0_1.py index f7c38d32..f3de2be5 100644 --- a/rhodecode/lib/dbmigrate/versions/020_version_2_0_1.py +++ b/rhodecode/lib/dbmigrate/versions/020_version_2_0_1.py @@ -39,7 +39,7 @@ def fixups(models, _SESSION): # fix all empty extern type users to default 'rhodecode' for usr in models.User.query().all(): if not usr.extern_name: - usr.extern_name = 'rhodecode' - usr.extern_type = 'rhodecode' + usr.extern_name = "rhodecode" + usr.extern_type = "rhodecode" _SESSION().add(usr) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/021_version_2_0_2.py b/rhodecode/lib/dbmigrate/versions/021_version_2_0_2.py index 7bc29908..c22f7af8 100644 --- a/rhodecode/lib/dbmigrate/versions/021_version_2_0_2.py +++ b/rhodecode/lib/dbmigrate/versions/021_version_2_0_2.py @@ -24,7 +24,7 @@ def get_by_key(cls, key): def get_repos_location(cls): - return get_by_key(cls, '/').ui_value + return get_by_key(cls, "/").ui_value def upgrade(migrate_engine): @@ -34,13 +34,13 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_2_0_1 + tbl = db_2_0_1.RepoGroup.__table__ - created_on = Column('created_on', DateTime(timezone=False), nullable=True, - default=datetime.datetime.now) + created_on = Column("created_on", DateTime(timezone=False), nullable=True, default=datetime.datetime.now) created_on.create(table=tbl) - #fix null values on certain columns when upgrading from older releases + # fix null values on certain columns when upgrading from older releases tbl = db_2_0_1.UserLog.__table__ col = tbl.columns.user_id col.alter(nullable=True) @@ -63,7 +63,7 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Fixing default created on for repo groups') + notify("Fixing default created on for repo groups") for gr in models.RepoGroup.get_all(): gr.created_on = datetime.datetime.now() @@ -71,15 +71,14 @@ def fixups(models, _SESSION): _SESSION().commit() repo_store_path = get_repos_location(models.RhodeCodeUi) - _store = os.path.join(repo_store_path, '.cache', 'largefiles') - notify('Setting largefiles usercache') + _store = os.path.join(repo_store_path, ".cache", "largefiles") + notify("Setting largefiles usercache") print(_store) - if not models.RhodeCodeUi.query().filter( - models.RhodeCodeUi.ui_key == 'usercache').scalar(): + if not models.RhodeCodeUi.query().filter(models.RhodeCodeUi.ui_key == "usercache").scalar(): largefiles = models.RhodeCodeUi() - largefiles.ui_section = 'largefiles' - largefiles.ui_key = 'usercache' + largefiles.ui_section = "largefiles" + largefiles.ui_key = "usercache" largefiles.ui_value = _store _SESSION().add(largefiles) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/022_version_2_0_2.py b/rhodecode/lib/dbmigrate/versions/022_version_2_0_2.py index 5d1bb5c5..8b89ad7d 100644 --- a/rhodecode/lib/dbmigrate/versions/022_version_2_0_2.py +++ b/rhodecode/lib/dbmigrate/versions/022_version_2_0_2.py @@ -36,17 +36,17 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('fixing new schema for landing_rev') + notify("fixing new schema for landing_rev") for repo in models.Repository.get_all(): - print(u'repo %s old landing rev is: %s' % (repo, repo.landing_rev)) + print("repo %s old landing rev is: %s" % (repo, repo.landing_rev)) _rev = repo.landing_rev[1] - _rev_type = 'rev' # default + _rev_type = "rev" # default - if _rev in ['default', 'master']: - _rev_type = 'branch' - elif _rev in ['tip']: - _rev_type = 'rev' + if _rev in ["default", "master"]: + _rev_type = "branch" + elif _rev in ["tip"]: + _rev_type = "rev" else: try: scm = repo.scm_instance @@ -54,17 +54,17 @@ def fixups(models, _SESSION): known_branches = scm.branches.keys() known_bookmarks = scm.bookmarks.keys() if _rev in known_branches: - _rev_type = 'branch' + _rev_type = "branch" elif _rev in known_bookmarks: - _rev_type = 'book' + _rev_type = "book" except Exception as e: print(e) - print('continue...') - #we don't want any error to break the process + print("continue...") + # we don't want any error to break the process pass - _new_landing_rev = '%s:%s' % (_rev_type, _rev) - print(u'setting to %s' % _new_landing_rev) + _new_landing_rev = "%s:%s" % (_rev_type, _rev) + print("setting to %s" % _new_landing_rev) repo.landing_rev = _new_landing_rev _SESSION().add(repo) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/024_version_2_1_0.py b/rhodecode/lib/dbmigrate/versions/024_version_2_1_0.py index f95e4cc0..c7b8161e 100644 --- a/rhodecode/lib/dbmigrate/versions/024_version_2_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/024_version_2_1_0.py @@ -18,8 +18,6 @@ from rhodecode.lib.dbmigrate.versions import _reset_base, notify log = logging.getLogger(__name__) - - def upgrade(migrate_engine): """ Upgrade operations go here. @@ -39,16 +37,15 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): from rhodecode.lib.utils2 import str2bool + # fake config because we cannot extract the proper values from .ini here - config = { - 'use_gravatar': 'true' - } + config = {"use_gravatar": "true"} Optional = models.Optional def get_by_name(cls, key): return cls.query().filter(cls.app_settings_name == key).scalar() - def create_or_update(cls, key, val=Optional(''), type=Optional('unicode')): + def create_or_update(cls, key, val=Optional(""), type=Optional("unicode")): res = get_by_name(cls, key) if not res: val = Optional.extract(val) @@ -64,29 +61,26 @@ def fixups(models, _SESSION): res.app_settings_type = type return res - notify('migrating options from .ini file') - use_gravatar = str2bool(config.get('use_gravatar')) - print('Setting gravatar use to: %s' % use_gravatar) - sett = create_or_update(models.RhodeCodeSetting, - 'use_gravatar', use_gravatar, 'bool') + notify("migrating options from .ini file") + use_gravatar = str2bool(config.get("use_gravatar")) + print("Setting gravatar use to: %s" % use_gravatar) + sett = create_or_update(models.RhodeCodeSetting, "use_gravatar", use_gravatar, "bool") _SESSION().add(sett) _SESSION.commit() # set the new format of gravatar URL gravatar_url = models.User.DEFAULT_GRAVATAR_URL - if config.get('alternative_gravatar_url'): - gravatar_url = config.get('alternative_gravatar_url') + if config.get("alternative_gravatar_url"): + gravatar_url = config.get("alternative_gravatar_url") - print('Setting gravatar url to:%s' % gravatar_url) - sett = create_or_update(models.RhodeCodeSetting, - 'gravatar_url', gravatar_url, 'unicode') + print("Setting gravatar url to:%s" % gravatar_url) + sett = create_or_update(models.RhodeCodeSetting, "gravatar_url", gravatar_url, "unicode") _SESSION().add(sett) _SESSION.commit() # now create new changed value of clone_url clone_uri_tmpl = models.Repository.DEFAULT_CLONE_URI - print('settings new clone url template to %s' % clone_uri_tmpl) + print("settings new clone url template to %s" % clone_uri_tmpl) - sett = create_or_update(models.RhodeCodeSetting, - 'clone_uri_tmpl', clone_uri_tmpl, 'unicode') + sett = create_or_update(models.RhodeCodeSetting, "clone_uri_tmpl", clone_uri_tmpl, "unicode") _SESSION().add(sett) _SESSION.commit() diff --git a/rhodecode/lib/dbmigrate/versions/025_version_2_1_0.py b/rhodecode/lib/dbmigrate/versions/025_version_2_1_0.py index 42582835..9d25f56b 100644 --- a/rhodecode/lib/dbmigrate/versions/025_version_2_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/025_version_2_1_0.py @@ -41,7 +41,7 @@ def fixups(models, _SESSION): def get_by_name(cls, key): return cls.query().filter(cls.app_settings_name == key).scalar() - def create_or_update(cls, key, val=Optional(''), type=Optional('unicode')): + def create_or_update(cls, key, val=Optional(""), type=Optional("unicode")): res = get_by_name(cls, key) if not res: val = Optional.extract(val) @@ -57,8 +57,9 @@ def fixups(models, _SESSION): res.app_settings_type = type return res - notify('Creating upgrade URL') - sett = create_or_update(models.RhodeCodeSetting, - 'update_url', models.RhodeCodeSetting.DEFAULT_UPDATE_URL, 'unicode') + notify("Creating upgrade URL") + sett = create_or_update( + models.RhodeCodeSetting, "update_url", models.RhodeCodeSetting.DEFAULT_UPDATE_URL, "unicode" + ) _SESSION().add(sett) _SESSION.commit() diff --git a/rhodecode/lib/dbmigrate/versions/027_version_2_2_0.py b/rhodecode/lib/dbmigrate/versions/027_version_2_2_0.py index 3898b50a..6ccdcce9 100644 --- a/rhodecode/lib/dbmigrate/versions/027_version_2_2_0.py +++ b/rhodecode/lib/dbmigrate/versions/027_version_2_2_0.py @@ -41,25 +41,24 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): # ** create default permissions ** # - #===================================== + # ===================================== for p in models.Permission.PERMS: if not get_by_key(models.Permission, p[0]): new_perm = models.Permission() new_perm.permission_name = p[0] - new_perm.permission_longname = p[0] #translation err with p[1] - print('Creating new permission %s' % p[0]) + new_perm.permission_longname = p[0] # translation err with p[1] + print("Creating new permission %s" % p[0]) _SESSION().add(new_perm) _SESSION().commit() # ** set default create_on_write to active - user = models.User.query().filter( - models.User.username == 'default').scalar() + user = models.User.query().filter(models.User.username == "default").scalar() - _def = 'hg.create.write_on_repogroup.true' + _def = "hg.create.write_on_repogroup.true" new = models.UserToPerm() new.user = user new.permission = get_by_key(models.Permission, _def) - print('Setting default to %s' % _def) + print("Setting default to %s" % _def) _SESSION().add(new) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/029_version_2_2_3.py b/rhodecode/lib/dbmigrate/versions/029_version_2_2_3.py index f0150334..8ab60de2 100644 --- a/rhodecode/lib/dbmigrate/versions/029_version_2_2_3.py +++ b/rhodecode/lib/dbmigrate/versions/029_version_2_2_3.py @@ -40,10 +40,10 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Adding grid items options now...') + notify("Adding grid items options now...") settings = [ - ('admin_grid_items', 25, 'int'), # old hardcoded value was 25 + ("admin_grid_items", 25, "int"), # old hardcoded value was 25 ] for name, default, type_ in settings: diff --git a/rhodecode/lib/dbmigrate/versions/031_version_2_2_3.py b/rhodecode/lib/dbmigrate/versions/031_version_2_2_3.py index 36c689e5..28790b2f 100644 --- a/rhodecode/lib/dbmigrate/versions/031_version_2_2_3.py +++ b/rhodecode/lib/dbmigrate/versions/031_version_2_2_3.py @@ -36,7 +36,7 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Creating repository states') + notify("Creating repository states") _state = models.Repository.STATE_CREATED for repo in models.Repository.get_all(): log.info('setting repo %s state to "%s"', repo, _state) diff --git a/rhodecode/lib/dbmigrate/versions/032_version_2_3_0.py b/rhodecode/lib/dbmigrate/versions/032_version_2_3_0.py index 264ecfdb..85256b5b 100644 --- a/rhodecode/lib/dbmigrate/versions/032_version_2_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/032_version_2_3_0.py @@ -28,11 +28,10 @@ def upgrade(migrate_engine): tbl = db_2_2_3.UserApiKeys.__table__ - role = Column('role', String(255), nullable=True) + role = Column("role", String(255), nullable=True) role.create(table=tbl) def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine - diff --git a/rhodecode/lib/dbmigrate/versions/033_version_2_3_0.py b/rhodecode/lib/dbmigrate/versions/033_version_2_3_0.py index 032194ed..6d41a0bc 100644 --- a/rhodecode/lib/dbmigrate/versions/033_version_2_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/033_version_2_3_0.py @@ -36,7 +36,7 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Fixing auth tokens roles') + notify("Fixing auth tokens roles") _role = models.UserApiKeys.ROLE_ALL for token in models.UserApiKeys.get_all(): log.info('setting key %s role to "%s"', token, _role) diff --git a/rhodecode/lib/dbmigrate/versions/034_version_2_3_0.py b/rhodecode/lib/dbmigrate/versions/034_version_2_3_0.py index 1d220923..a5bc4199 100644 --- a/rhodecode/lib/dbmigrate/versions/034_version_2_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/034_version_2_3_0.py @@ -22,7 +22,7 @@ def get_by_name(cls, key): return cls.query().filter(cls.app_settings_name == key).scalar() -def get_by_name_or_create(cls, key, val='', type='unicode'): +def get_by_name_or_create(cls, key, val="", type="unicode"): res = get_by_name(cls, key) if not res: res = cls(key, val, type) @@ -47,9 +47,9 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Fixing existing GA code into new format') - cur_code = get_by_name(models.RhodeCodeSetting, 'ga_code') - val = ''' + notify("Fixing existing GA code into new format") + cur_code = get_by_name(models.RhodeCodeSetting, "ga_code") + val = """ ''' - if cur_code and getattr(cur_code, 'app_settings_value', ''): - cur_val = getattr(cur_code, 'app_settings_value', '') - val = val.replace('_GACODE_', cur_val) - notify('Found GA code %s, migrating' % cur_val) - new = get_by_name_or_create(models.RhodeCodeSetting, 'pre_code', val) +""" + if cur_code and getattr(cur_code, "app_settings_value", ""): + cur_val = getattr(cur_code, "app_settings_value", "") + val = val.replace("_GACODE_", cur_val) + notify("Found GA code %s, migrating" % cur_val) + new = get_by_name_or_create(models.RhodeCodeSetting, "pre_code", val) new.app_settings_value = val _SESSION().add(new) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/035_version_2_3_0.py b/rhodecode/lib/dbmigrate/versions/035_version_2_3_0.py index b5ca8677..1e872cb8 100644 --- a/rhodecode/lib/dbmigrate/versions/035_version_2_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/035_version_2_3_0.py @@ -28,7 +28,7 @@ def upgrade(migrate_engine): tbl = db_2_3_0_0.ChangesetComment.__table__ - renderer = Column('renderer', Unicode(64), nullable=True) + renderer = Column("renderer", Unicode(64), nullable=True) renderer.create(table=tbl) diff --git a/rhodecode/lib/dbmigrate/versions/036_version_2_3_0.py b/rhodecode/lib/dbmigrate/versions/036_version_2_3_0.py index 85f42048..0a35bffa 100644 --- a/rhodecode/lib/dbmigrate/versions/036_version_2_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/036_version_2_3_0.py @@ -36,9 +36,9 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Setting default renderer to rst') + notify("Setting default renderer to rst") for cs_comment in models.ChangesetComment.get_all(): - print('comment_id %s renderer rst' % (cs_comment.comment_id)) - cs_comment.renderer = 'rst' + print("comment_id %s renderer rst" % (cs_comment.comment_id)) + cs_comment.renderer = "rst" _SESSION().add(cs_comment) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/038_version_2_3_0.py b/rhodecode/lib/dbmigrate/versions/038_version_2_3_0.py index e5eb9e0d..17c89e05 100644 --- a/rhodecode/lib/dbmigrate/versions/038_version_2_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/038_version_2_3_0.py @@ -40,11 +40,11 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - notify('Adding revision look items options now...') + notify("Adding revision look items options now...") settings = [ - ('show_revision_number', True, 'bool'), - ('show_sha_length', 12, 'int'), + ("show_revision_number", True, "bool"), + ("show_sha_length", 12, "int"), ] for name, default, type_ in settings: diff --git a/rhodecode/lib/dbmigrate/versions/039_version_2_3_0.py b/rhodecode/lib/dbmigrate/versions/039_version_2_3_0.py index e1ebacb9..842bf266 100644 --- a/rhodecode/lib/dbmigrate/versions/039_version_2_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/039_version_2_3_0.py @@ -28,10 +28,10 @@ def upgrade(migrate_engine): tbl = db_2_3_0_2.PullRequest.__table__ - _last_merge_org_rev = Column('last_merge_org_rev', String(40), nullable=True) - _last_merge_other_rev = Column('last_merge_other_rev', String(40), nullable=True) - _last_merge_status = Column('merge_status', Integer(), nullable=True) - merge_rev = Column('merge_rev', String(40), nullable=True) + _last_merge_org_rev = Column("last_merge_org_rev", String(40), nullable=True) + _last_merge_other_rev = Column("last_merge_other_rev", String(40), nullable=True) + _last_merge_status = Column("merge_status", Integer(), nullable=True) + merge_rev = Column("merge_rev", String(40), nullable=True) _last_merge_org_rev.create(table=tbl) _last_merge_other_rev.create(table=tbl) _last_merge_status.create(table=tbl) diff --git a/rhodecode/lib/dbmigrate/versions/040_version_3_0_0.py b/rhodecode/lib/dbmigrate/versions/040_version_3_0_0.py index fb09580a..e1d831f2 100644 --- a/rhodecode/lib/dbmigrate/versions/040_version_3_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/040_version_3_0_0.py @@ -4,8 +4,8 @@ from sqlalchemy import * from rhodecode.model import meta from rhodecode.lib.dbmigrate.versions import _reset_base, notify -from rhodecode.lib.dbmigrate.utils import ( - create_default_object_permission, create_default_permissions) +from rhodecode.lib.dbmigrate.utils import create_default_object_permission, create_default_permissions + log = logging.getLogger(__name__) @@ -29,11 +29,11 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): # create default permissions create_default_permissions(_SESSION, models) - log.info('created default global permissions definitions') + log.info("created default global permissions definitions") _SESSION().commit() # fix default object permissions create_default_object_permission(_SESSION, models) - log.info('created default permission') + log.info("created default permission") _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/041_version_3_0_0.py b/rhodecode/lib/dbmigrate/versions/041_version_3_0_0.py index 9eeadd88..6dda3824 100644 --- a/rhodecode/lib/dbmigrate/versions/041_version_3_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/041_version_3_0_0.py @@ -24,7 +24,7 @@ def get_by_key(cls, key): def create_or_update_hook(cls, key, val, SESSION): new_ui = get_by_key(cls, key) or cls() - new_ui.ui_section = 'hooks' + new_ui.ui_section = "hooks" new_ui.ui_active = True new_ui.ui_key = key new_ui.ui_value = val @@ -50,7 +50,6 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - cleanup_if_present = ( models.RhodeCodeUi.HOOK_REPO_SIZE, models.RhodeCodeUi.HOOK_PRE_PULL, @@ -60,26 +59,22 @@ def fixups(models, _SESSION): models.RhodeCodeUi.HOOK_PRE_PULL_GIT, models.RhodeCodeUi.HOOK_PULL_GIT, models.RhodeCodeUi.HOOK_PRE_PUSH_GIT, - models.RhodeCodeUi.HOOK_PUSH_GIT) + models.RhodeCodeUi.HOOK_PUSH_GIT, + ) for hook in cleanup_if_present: - ui_cfg = models.RhodeCodeUi.query().filter( - models.RhodeCodeUi.ui_key == hook).scalar() + ui_cfg = models.RhodeCodeUi.query().filter(models.RhodeCodeUi.ui_key == hook).scalar() if ui_cfg is not None: log.info('Removing RhodeCodeUI for hook "%s".', hook) _SESSION().delete(ui_cfg) to_add = [ - (models.RhodeCodeUi.HOOK_REPO_SIZE, - 'python:vcsserver.hooks.repo_size'), - (models.RhodeCodeUi.HOOK_PRE_PULL, - 'python:vcsserver.hooks.pre_pull'), - (models.RhodeCodeUi.HOOK_PRE_PUSH, - 'python:vcsserver.hooks.pre_push'), - (models.RhodeCodeUi.HOOK_PULL, - 'python:vcsserver.hooks.log_pull_action'), - (models.RhodeCodeUi.HOOK_PUSH, - 'python:vcsserver.hooks.log_push_action')] + (models.RhodeCodeUi.HOOK_REPO_SIZE, "python:vcsserver.hooks.repo_size"), + (models.RhodeCodeUi.HOOK_PRE_PULL, "python:vcsserver.hooks.pre_pull"), + (models.RhodeCodeUi.HOOK_PRE_PUSH, "python:vcsserver.hooks.pre_push"), + (models.RhodeCodeUi.HOOK_PULL, "python:vcsserver.hooks.log_pull_action"), + (models.RhodeCodeUi.HOOK_PUSH, "python:vcsserver.hooks.log_push_action"), + ] for hook, value in to_add: log.info('Adding RhodeCodeUI for hook "%s".', hook) diff --git a/rhodecode/lib/dbmigrate/versions/043_version_3_1_0.py b/rhodecode/lib/dbmigrate/versions/043_version_3_1_0.py index c22aabbd..2fa0eb50 100644 --- a/rhodecode/lib/dbmigrate/versions/043_version_3_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/043_version_3_1_0.py @@ -28,7 +28,7 @@ def upgrade(migrate_engine): tbl = db_3_0_0_0.Gist.__table__ - acl_level = Column('acl_level', Unicode(128), nullable=True) + acl_level = Column("acl_level", Unicode(128), nullable=True) acl_level.create(table=tbl) diff --git a/rhodecode/lib/dbmigrate/versions/044_version_3_1_0.py b/rhodecode/lib/dbmigrate/versions/044_version_3_1_0.py index 105ef188..d84580a8 100644 --- a/rhodecode/lib/dbmigrate/versions/044_version_3_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/044_version_3_1_0.py @@ -33,9 +33,8 @@ def upgrade(migrate_engine): # Add pull_request_version to ChangesetComment tbl = db_3_1_0_1.ChangesetComment.__table__ pull_request_version_id = Column( - "pull_request_version_id", Integer(), - ForeignKey('pull_request_versions.pull_request_version_id'), - nullable=True) + "pull_request_version_id", Integer(), ForeignKey("pull_request_versions.pull_request_version_id"), nullable=True + ) pull_request_version_id.create(table=tbl) diff --git a/rhodecode/lib/dbmigrate/versions/046_version_3_3_0.py b/rhodecode/lib/dbmigrate/versions/046_version_3_3_0.py index 5747c2d8..90f4b85d 100644 --- a/rhodecode/lib/dbmigrate/versions/046_version_3_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/046_version_3_3_0.py @@ -25,6 +25,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_3_3_0_0 + init_model_encryption(db_3_3_0_0) fixups(db_3_3_0_0, meta.Session) @@ -36,7 +37,7 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): for repo in models.Repository.get_all(): - _lock_info = repo._locked.split(':') if repo._locked else [] + _lock_info = repo._locked.split(":") if repo._locked else [] if len(_lock_info) == 2: _lock_info.append(repo.LOCK_AUTOMATIC) repo.locked = _lock_info diff --git a/rhodecode/lib/dbmigrate/versions/047_version_3_5_0.py b/rhodecode/lib/dbmigrate/versions/047_version_3_5_0.py index 7d1c50e8..bf04129c 100644 --- a/rhodecode/lib/dbmigrate/versions/047_version_3_5_0.py +++ b/rhodecode/lib/dbmigrate/versions/047_version_3_5_0.py @@ -26,5 +26,3 @@ def upgrade(migrate_engine): def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine - - diff --git a/rhodecode/lib/dbmigrate/versions/048_version_3_8_0.py b/rhodecode/lib/dbmigrate/versions/048_version_3_8_0.py index 51772357..722d7d95 100644 --- a/rhodecode/lib/dbmigrate/versions/048_version_3_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/048_version_3_8_0.py @@ -1,5 +1,3 @@ - - import hashlib import logging @@ -36,31 +34,27 @@ def upgrade(migrate_engine): clone_uri_column = repository.columns.clone_uri indexes = _get_indexes_list(migrate_engine, repository.name) - repo_name_indexes = [ - i['name'] for i in indexes if 'repo_name' in i['column_names']] + repo_name_indexes = [i["name"] for i in indexes if "repo_name" in i["column_names"]] constraints = _get_unique_constraint_list(migrate_engine, repository.name) - repo_name_constraints = [ - c['name'] for c in constraints if 'repo_name' in c['column_names']] + repo_name_constraints = [c["name"] for c in constraints if "repo_name" in c["column_names"]] with op.batch_alter_table(repository.name) as batch_op: - repo_name_idx = 'r_repo_name_idx' + repo_name_idx = "r_repo_name_idx" if repo_name_idx in repo_name_indexes: batch_op.drop_index(repo_name_idx) for name in repo_name_constraints: if name: # sqlite can have this empty, then it raises an error - batch_op.drop_constraint(name, type_='unique') + batch_op.drop_constraint(name, type_="unique") batch_op.alter_column(repo_name_column.name, type_=Text) batch_op.alter_column(clone_uri_column.name, type_=Text) - batch_op.create_index( - 'r_repo_name_idx', ['repo_name'], mysql_length=255) - batch_op.add_column(Column('repo_name_hash', String(40), unique=False)) + batch_op.create_index("r_repo_name_idx", ["repo_name"], mysql_length=255) + batch_op.add_column(Column("repo_name_hash", String(40), unique=False)) _generate_repo_name_hashes(db_3_7_0_0, op, meta.Session) with op.batch_alter_table(repository.name) as batch_op: - batch_op.create_unique_constraint( - 'uq_repo_name_hash', ['repo_name_hash']) + batch_op.create_unique_constraint("uq_repo_name_hash", ["repo_name_hash"]) def downgrade(migrate_engine): @@ -71,8 +65,8 @@ def _generate_repo_name_hashes(models, op, session): repositories = models.Repository.get_all() for repository in repositories: hash_ = sha1_safe(repository.repo_name) - params = {'hash': hash_, 'id': repository.repo_id} - query = text('UPDATE repositories SET repo_name_hash = :hash WHERE repo_id = :id').bindparams(**params) + params = {"hash": hash_, "id": repository.repo_id} + query = text("UPDATE repositories SET repo_name_hash = :hash WHERE repo_id = :id").bindparams(**params) op.execute(query) session().commit() diff --git a/rhodecode/lib/dbmigrate/versions/049_version_4_0_0.py b/rhodecode/lib/dbmigrate/versions/049_version_4_0_0.py index f42c4877..ade00d2e 100644 --- a/rhodecode/lib/dbmigrate/versions/049_version_4_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/049_version_4_0_0.py @@ -1,5 +1,3 @@ - - import logging import sqlalchemy as sa @@ -27,22 +25,17 @@ def upgrade(migrate_engine): op = Operations(context) op.create_table( - 'external_identities', - sa.Column('provider_name', sa.Unicode(255), primary_key=True), - sa.Column('local_user_id', sa.Integer(), - sa.ForeignKey('users.user_id'), primary_key=True), - - sa.Column('external_id', sa.Unicode(255), primary_key=True), - sa.Column('external_username', sa.Unicode(1024), default=u''), - - sa.Column('access_token', sa.String(1024), default=u''), - sa.Column('alt_token', sa.String(1024), default=u''), - sa.Column('token_secret', sa.String(1024), default=u'') + "external_identities", + sa.Column("provider_name", sa.Unicode(255), primary_key=True), + sa.Column("local_user_id", sa.Integer(), sa.ForeignKey("users.user_id"), primary_key=True), + sa.Column("external_id", sa.Unicode(255), primary_key=True), + sa.Column("external_username", sa.Unicode(1024), default=""), + sa.Column("access_token", sa.String(1024), default=""), + sa.Column("alt_token", sa.String(1024), default=""), + sa.Column("token_secret", sa.String(1024), default=""), ) - op.create_index('local_user_id_idx', 'external_identities', - ['local_user_id']) - op.create_index('external_id_idx', 'external_identities', - ['external_id']) + op.create_index("local_user_id_idx", "external_identities", ["local_user_id"]) + op.create_index("external_id_idx", "external_identities", ["external_id"]) def downgrade(migrate_engine): diff --git a/rhodecode/lib/dbmigrate/versions/050_version_4_0_0.py b/rhodecode/lib/dbmigrate/versions/050_version_4_0_0.py index b59f6333..de2cb045 100644 --- a/rhodecode/lib/dbmigrate/versions/050_version_4_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/050_version_4_0_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy.orm.attributes import flag_modified @@ -17,6 +15,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_3_7_0_0 + init_model_encryption(db_3_7_0_0) fixups(db_3_7_0_0, meta.Session) @@ -28,10 +27,8 @@ def downgrade(migrate_engine): def fixups(models, Session): for repo in models.Repository.get_all(): if repo.clone_uri: - log.info('Encrypting clone uri in repo %s', repo) - flag_modified(repo, 'clone_uri') + log.info("Encrypting clone uri in repo %s", repo) + flag_modified(repo, "clone_uri") Session().add(repo) Session().commit() - - diff --git a/rhodecode/lib/dbmigrate/versions/051_version_4_0_0.py b/rhodecode/lib/dbmigrate/versions/051_version_4_0_0.py index ec029001..48b37b1d 100644 --- a/rhodecode/lib/dbmigrate/versions/051_version_4_0_0.py +++ b/rhodecode/lib/dbmigrate/versions/051_version_4_0_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy.orm.attributes import flag_modified @@ -17,6 +15,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_3_7_0_0 + init_model_encryption(db_3_7_0_0) fixups(db_3_7_0_0, meta.Session) @@ -28,26 +27,23 @@ def downgrade(migrate_engine): AUTH_PLUGINS_SETTING = "auth_plugins" PLUGIN_ID_MAP = { - 'rhodecode.lib.auth_modules.auth_crowd': 'egg:rhodecode-enterprise-ce#crowd', - 'rhodecode.lib.auth_modules.auth_container': 'egg:rhodecode-enterprise-ce#container', - 'rhodecode.lib.auth_modules.auth_jasig_cas': 'egg:rhodecode-enterprise-ce#jasig_cas', - 'rhodecode.lib.auth_modules.auth_ldap': 'egg:rhodecode-enterprise-ce#ldap', - 'rhodecode.lib.auth_modules.auth_pam': 'egg:rhodecode-enterprise-ce#pam', - 'rhodecode.lib.auth_modules.auth_rhodecode': 'egg:rhodecode-enterprise-ce#rhodecode', - - 'rhodecode.lib.auth_modules.auth_bitbucket': 'egg:rhodecode-enterprise-ee#bitbucket', - 'rhodecode.lib.auth_modules.auth_github': 'egg:rhodecode-enterprise-ee#github', - 'rhodecode.lib.auth_modules.auth_google': 'egg:rhodecode-enterprise-ee#google', - 'rhodecode.lib.auth_modules.auth_ldap_group': 'egg:rhodecode-enterprise-ee#ldap_group', - 'rhodecode.lib.auth_modules.auth_token': 'egg:rhodecode-enterprise-ee#token', - 'rhodecode.lib.auth_modules.auth_twitter': 'egg:rhodecode-enterprise-ee#twitter', + "rhodecode.lib.auth_modules.auth_crowd": "egg:rhodecode-enterprise-ce#crowd", + "rhodecode.lib.auth_modules.auth_container": "egg:rhodecode-enterprise-ce#container", + "rhodecode.lib.auth_modules.auth_jasig_cas": "egg:rhodecode-enterprise-ce#jasig_cas", + "rhodecode.lib.auth_modules.auth_ldap": "egg:rhodecode-enterprise-ce#ldap", + "rhodecode.lib.auth_modules.auth_pam": "egg:rhodecode-enterprise-ce#pam", + "rhodecode.lib.auth_modules.auth_rhodecode": "egg:rhodecode-enterprise-ce#rhodecode", + "rhodecode.lib.auth_modules.auth_bitbucket": "egg:rhodecode-enterprise-ee#bitbucket", + "rhodecode.lib.auth_modules.auth_github": "egg:rhodecode-enterprise-ee#github", + "rhodecode.lib.auth_modules.auth_google": "egg:rhodecode-enterprise-ee#google", + "rhodecode.lib.auth_modules.auth_ldap_group": "egg:rhodecode-enterprise-ee#ldap_group", + "rhodecode.lib.auth_modules.auth_token": "egg:rhodecode-enterprise-ee#token", + "rhodecode.lib.auth_modules.auth_twitter": "egg:rhodecode-enterprise-ee#twitter", } def fixups(models, Session): - - query = models.RhodeCodeSetting.query().filter( - models.RhodeCodeSetting.app_settings_name == AUTH_PLUGINS_SETTING) + query = models.RhodeCodeSetting.query().filter(models.RhodeCodeSetting.app_settings_name == AUTH_PLUGINS_SETTING) plugin_setting = query.scalar() plugins = plugin_setting.app_settings_value @@ -62,14 +58,13 @@ def fixups(models, Session): new_plugins.append(plugin_id) missed_plugins.append(plugin_id) - plugin_setting.app_settings_value = ','.join(new_plugins) + plugin_setting.app_settings_value = ",".join(new_plugins) log.info("Migration of the auth plugin IDs") log.info("Original setting value: %s", plugins) log.info("New setting value: %s", new_plugins) if missed_plugins: log.warning("Unknown plugin ids: %s", missed_plugins) - log.warning( - "Please check the auth settings and re-enable needed plugins.") + log.warning("Please check the auth settings and re-enable needed plugins.") Session().commit() diff --git a/rhodecode/lib/dbmigrate/versions/052_version_4_1_0.py b/rhodecode/lib/dbmigrate/versions/052_version_4_1_0.py index dde7c844..ff4e6132 100644 --- a/rhodecode/lib/dbmigrate/versions/052_version_4_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/052_version_4_1_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy.orm.attributes import flag_modified @@ -17,6 +15,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_3_7_0_0 + init_model_encryption(db_3_7_0_0) fixups(db_3_7_0_0, meta.Session) @@ -28,21 +27,20 @@ def downgrade(migrate_engine): AUTH_PLUGINS_SETTING = "auth_plugins" PLUGIN_RENAME_MAP = { - 'egg:rhodecode-enterprise-ce#container': 'egg:rhodecode-enterprise-ce#headers', + "egg:rhodecode-enterprise-ce#container": "egg:rhodecode-enterprise-ce#headers", } SETTINGS_RENAME_MAP = { - 'auth_container_cache_ttl': 'auth_headers_cache_ttl', - 'auth_container_clean_username': 'auth_headers_clean_username', - 'auth_container_enabled': 'auth_headers_enabled', - 'auth_container_fallback_header': 'auth_headers_fallback_header', - 'auth_container_header': 'auth_headers_header', + "auth_container_cache_ttl": "auth_headers_cache_ttl", + "auth_container_clean_username": "auth_headers_clean_username", + "auth_container_enabled": "auth_headers_enabled", + "auth_container_fallback_header": "auth_headers_fallback_header", + "auth_container_header": "auth_headers_header", } def rename_plugins(models, Session): - query = models.RhodeCodeSetting.query().filter( - models.RhodeCodeSetting.app_settings_name == AUTH_PLUGINS_SETTING) + query = models.RhodeCodeSetting.query().filter(models.RhodeCodeSetting.app_settings_name == AUTH_PLUGINS_SETTING) plugin_setting = query.scalar() plugins = plugin_setting.app_settings_value @@ -55,7 +53,7 @@ def rename_plugins(models, Session): else: new_plugins.append(plugin_id) - plugin_setting.app_settings_value = ','.join(new_plugins) + plugin_setting.app_settings_value = ",".join(new_plugins) log.info("Rename of auth plugin IDs") log.info("Original setting value: %s", plugins) @@ -64,13 +62,11 @@ def rename_plugins(models, Session): def rename_plugin_settings(models, Session): for old_name, new_name in SETTINGS_RENAME_MAP.items(): - query = models.RhodeCodeSetting.query().filter( - models.RhodeCodeSetting.app_settings_name == old_name) + query = models.RhodeCodeSetting.query().filter(models.RhodeCodeSetting.app_settings_name == old_name) setting = query.scalar() if setting: setting.app_settings_name = new_name - log.info( - 'Rename of plugin setting "%s" to "%s"', old_name, new_name) + log.info('Rename of plugin setting "%s" to "%s"', old_name, new_name) def fixups(models, Session): diff --git a/rhodecode/lib/dbmigrate/versions/053_version_4_1_0.py b/rhodecode/lib/dbmigrate/versions/053_version_4_1_0.py index f0d2b980..d9a275e8 100644 --- a/rhodecode/lib/dbmigrate/versions/053_version_4_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/053_version_4_1_0.py @@ -1,5 +1,3 @@ - - import logging from rhodecode.lib.dbmigrate.versions import _reset_base @@ -15,6 +13,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_3_7_0_0 + init_model_encryption(db_3_7_0_0) fixups(db_3_7_0_0, meta.Session) @@ -26,13 +25,12 @@ def downgrade(migrate_engine): AUTH_PLUGINS_SETTING = "auth_plugins" PLUGIN_RENAME_MAP = { - 'egg:rhodecode-enterprise-ee#token': 'egg:rhodecode-enterprise-ce#token', + "egg:rhodecode-enterprise-ee#token": "egg:rhodecode-enterprise-ce#token", } def rename_plugins(models, Session): - query = models.RhodeCodeSetting.query().filter( - models.RhodeCodeSetting.app_settings_name == AUTH_PLUGINS_SETTING) + query = models.RhodeCodeSetting.query().filter(models.RhodeCodeSetting.app_settings_name == AUTH_PLUGINS_SETTING) plugin_setting = query.scalar() plugins = plugin_setting.app_settings_value @@ -45,7 +43,7 @@ def rename_plugins(models, Session): else: new_plugins.append(plugin_id) - plugin_setting.app_settings_value = ','.join(new_plugins) + plugin_setting.app_settings_value = ",".join(new_plugins) log.info("Rename of auth plugin IDs") log.info("Original setting value: %s", plugins) diff --git a/rhodecode/lib/dbmigrate/versions/054_version_4_1_0.py b/rhodecode/lib/dbmigrate/versions/054_version_4_1_0.py index 7ad873ae..c5d2c229 100644 --- a/rhodecode/lib/dbmigrate/versions/054_version_4_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/054_version_4_1_0.py @@ -1,5 +1,3 @@ - - import logging from collections import namedtuple @@ -16,6 +14,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_3_7_0_0 + init_model_encryption(db_3_7_0_0) fixups(db_3_7_0_0, meta.Session) @@ -27,20 +26,18 @@ def downgrade(migrate_engine): AUTH_PLUGINS_SETTING = "auth_plugins" EXTERN_TYPE_RENAME_MAP = { - 'container': 'headers', + "container": "headers", } # Only used for logging purposes. -RenameExternTypeOperation = namedtuple( - 'RenameExternTypeOperation', ['user', 'old', 'new']) +RenameExternTypeOperation = namedtuple("RenameExternTypeOperation", ["user", "old", "new"]) def fixups(models, Session): operations = [] # Rename the extern_type attribute - query = models.User.query().filter( - models.User.extern_type.in_(EXTERN_TYPE_RENAME_MAP.keys())) + query = models.User.query().filter(models.User.extern_type.in_(EXTERN_TYPE_RENAME_MAP.keys())) for user in query: old = user.extern_type new = EXTERN_TYPE_RENAME_MAP[old] diff --git a/rhodecode/lib/dbmigrate/versions/055_version_4_3_0.py b/rhodecode/lib/dbmigrate/versions/055_version_4_3_0.py index d52902a6..7e0f471b 100644 --- a/rhodecode/lib/dbmigrate/versions/055_version_4_3_0.py +++ b/rhodecode/lib/dbmigrate/versions/055_version_4_3_0.py @@ -1,5 +1,3 @@ - - import logging import sqlalchemy as sa diff --git a/rhodecode/lib/dbmigrate/versions/057_version_4_4_0.py b/rhodecode/lib/dbmigrate/versions/057_version_4_4_0.py index 420b00e2..e19f94fc 100644 --- a/rhodecode/lib/dbmigrate/versions/057_version_4_4_0.py +++ b/rhodecode/lib/dbmigrate/versions/057_version_4_4_0.py @@ -30,6 +30,7 @@ def upgrade(migrate_engine): child_repos_only = db_4_4_0_1.Integration.child_repos_only child_repos_only.create(table=tbl) + def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine diff --git a/rhodecode/lib/dbmigrate/versions/058_version_4_4_0.py b/rhodecode/lib/dbmigrate/versions/058_version_4_4_0.py index 5642cc06..442cc899 100644 --- a/rhodecode/lib/dbmigrate/versions/058_version_4_4_0.py +++ b/rhodecode/lib/dbmigrate/versions/058_version_4_4_0.py @@ -11,8 +11,7 @@ log = logging.getLogger(__name__) def get_all_settings(models): settings = { - 'rhodecode_' + result.app_settings_name: result.app_settings_value - for result in models.RhodeCodeSetting.query() + "rhodecode_" + result.app_settings_name: result.app_settings_value for result in models.RhodeCodeSetting.query() } return settings @@ -35,13 +34,11 @@ def create_ui_section_value(models, Session, section, val, key=None, active=True return new_ui -def create_or_update_ui( - models, Session, section, key, value=None, active=None): +def create_or_update_ui(models, Session, section, key, value=None, active=None): ui = get_ui_by_section_and_key(models, section, key) if not ui: active = True if active is None else active - create_ui_section_value( - models, Session, section, value, key=key, active=active) + create_ui_section_value(models, Session, section, value, key=key, active=active) else: if active is not None: ui.ui_active = active @@ -57,6 +54,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_4_4_0_1 + init_model_encryption(db_4_4_0_1) fixups(db_4_4_0_1, meta.Session) @@ -69,17 +67,11 @@ def downgrade(migrate_engine): def fixups(models, Session): current_settings = get_all_settings(models) - svn_proxy_enabled = safe_str(current_settings.get( - 'rhodecode_proxy_subversion_http_requests', 'False')) - svn_proxy_url = current_settings.get( - 'rhodecode_subversion_http_server_url', '') + svn_proxy_enabled = safe_str(current_settings.get("rhodecode_proxy_subversion_http_requests", "False")) + svn_proxy_url = current_settings.get("rhodecode_subversion_http_server_url", "") - create_or_update_ui( - models, Session, 'vcs_svn_proxy', 'http_requests_enabled', - value=svn_proxy_enabled) + create_or_update_ui(models, Session, "vcs_svn_proxy", "http_requests_enabled", value=svn_proxy_enabled) - create_or_update_ui( - models, Session, 'vcs_svn_proxy', 'http_server_url', - value=svn_proxy_url) + create_or_update_ui(models, Session, "vcs_svn_proxy", "http_server_url", value=svn_proxy_url) Session().commit() diff --git a/rhodecode/lib/dbmigrate/versions/059_version_4_4_0.py b/rhodecode/lib/dbmigrate/versions/059_version_4_4_0.py index f14cdd33..ccd0c44c 100644 --- a/rhodecode/lib/dbmigrate/versions/059_version_4_4_0.py +++ b/rhodecode/lib/dbmigrate/versions/059_version_4_4_0.py @@ -30,6 +30,7 @@ def upgrade(migrate_engine): db_4_4_0_2.RepoReviewRuleUser.__table__.create() db_4_4_0_2.RepoReviewRuleUserGroup.__table__.create() + def downgrade(migrate_engine): meta = MetaData() meta.bind = migrate_engine diff --git a/rhodecode/lib/dbmigrate/versions/060_version_4_5_0.py b/rhodecode/lib/dbmigrate/versions/060_version_4_5_0.py index 3a632283..3613d553 100644 --- a/rhodecode/lib/dbmigrate/versions/060_version_4_5_0.py +++ b/rhodecode/lib/dbmigrate/versions/060_version_4_5_0.py @@ -26,8 +26,8 @@ def upgrade(migrate_engine): _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_4_5_0_0 - db_4_5_0_0.PullRequestReviewers.reasons.create( - table=db_4_5_0_0.PullRequestReviewers.__table__) + db_4_5_0_0.PullRequestReviewers.reasons.create(table=db_4_5_0_0.PullRequestReviewers.__table__) + def downgrade(migrate_engine): meta = MetaData() diff --git a/rhodecode/lib/dbmigrate/versions/061_version_4_5_0.py b/rhodecode/lib/dbmigrate/versions/061_version_4_5_0.py index a62ba8c2..db73935d 100644 --- a/rhodecode/lib/dbmigrate/versions/061_version_4_5_0.py +++ b/rhodecode/lib/dbmigrate/versions/061_version_4_5_0.py @@ -3,8 +3,8 @@ import logging from sqlalchemy import * from rhodecode.model import meta from rhodecode.lib.dbmigrate.versions import _reset_base, notify -from rhodecode.lib.dbmigrate.utils import ( - create_default_object_permission, create_default_permissions) +from rhodecode.lib.dbmigrate.utils import create_default_object_permission, create_default_permissions + log = logging.getLogger(__name__) @@ -27,11 +27,11 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): # create default permissions create_default_permissions(_SESSION, models) - log.info('created default global permissions definitions') + log.info("created default global permissions definitions") _SESSION().commit() # fix default object permissions create_default_object_permission(_SESSION, models) - log.info('created default permission') + log.info("created default permission") _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/062_version_4_5_0.py b/rhodecode/lib/dbmigrate/versions/062_version_4_5_0.py index 0e861936..e10c2d2d 100644 --- a/rhodecode/lib/dbmigrate/versions/062_version_4_5_0.py +++ b/rhodecode/lib/dbmigrate/versions/062_version_4_5_0.py @@ -17,12 +17,12 @@ def upgrade(migrate_engine): # Add shadow merge ref column to pull request table. pr_table = db.PullRequest.__table__ - pr_col = Column('shadow_merge_ref', Unicode(255), nullable=True) + pr_col = Column("shadow_merge_ref", Unicode(255), nullable=True) pr_col.create(table=pr_table) # Add shadow merge ref column to pull request version table. pr_version_table = db.PullRequestVersion.__table__ - pr_version_col = Column('shadow_merge_ref', Unicode(255), nullable=True) + pr_version_col = Column("shadow_merge_ref", Unicode(255), nullable=True) pr_version_col.create(table=pr_version_table) diff --git a/rhodecode/lib/dbmigrate/versions/063_version_4_5_0.py b/rhodecode/lib/dbmigrate/versions/063_version_4_5_0.py index d6a650e2..c3f40280 100644 --- a/rhodecode/lib/dbmigrate/versions/063_version_4_5_0.py +++ b/rhodecode/lib/dbmigrate/versions/063_version_4_5_0.py @@ -17,8 +17,7 @@ def upgrade(migrate_engine): # Add personal column to RepoGroup table. rg_table = db.RepoGroup.__table__ - rg_col = Column( - 'personal', Boolean(), nullable=True, unique=None, default=None) + rg_col = Column("personal", Boolean(), nullable=True, unique=None, default=None) rg_col.create(table=rg_table) diff --git a/rhodecode/lib/dbmigrate/versions/064_version_4_6_0.py b/rhodecode/lib/dbmigrate/versions/064_version_4_6_0.py index ba252f40..2b1a1b89 100644 --- a/rhodecode/lib/dbmigrate/versions/064_version_4_6_0.py +++ b/rhodecode/lib/dbmigrate/versions/064_version_4_6_0.py @@ -17,11 +17,10 @@ def upgrade(migrate_engine): # add comment type and link to resolve by id comment_table = db.ChangesetComment.__table__ - col1 = Column('comment_type', Unicode(128), nullable=True) + col1 = Column("comment_type", Unicode(128), nullable=True) col1.create(table=comment_table) - col1 = Column('resolved_comment_id', Integer(), - ForeignKey('changeset_comments.comment_id'), nullable=True) + col1 = Column("resolved_comment_id", Integer(), ForeignKey("changeset_comments.comment_id"), nullable=True) col1.create(table=comment_table) diff --git a/rhodecode/lib/dbmigrate/versions/065_version_4_7_0.py b/rhodecode/lib/dbmigrate/versions/065_version_4_7_0.py index 24710780..40c9237d 100644 --- a/rhodecode/lib/dbmigrate/versions/065_version_4_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/065_version_4_7_0.py @@ -13,7 +13,7 @@ def get_by_key(cls, key): def create_or_update_hook(cls, key, val, SESSION): new_ui = get_by_key(cls, key) or cls() - new_ui.ui_section = 'hooks' + new_ui.ui_section = "hooks" new_ui.ui_active = True new_ui.ui_key = key new_ui.ui_value = val @@ -39,25 +39,20 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - - cleanup_if_present = ( - models.RhodeCodeUi.HOOK_PRETX_PUSH, - ) + cleanup_if_present = (models.RhodeCodeUi.HOOK_PRETX_PUSH,) for hook in cleanup_if_present: - ui_cfg = models.RhodeCodeUi.query().filter( - models.RhodeCodeUi.ui_key == hook).scalar() + ui_cfg = models.RhodeCodeUi.query().filter(models.RhodeCodeUi.ui_key == hook).scalar() if ui_cfg is not None: log.info('Removing RhodeCodeUI for hook "%s".', hook) _SESSION().delete(ui_cfg) to_add = [ - (models.RhodeCodeUi.HOOK_PRETX_PUSH, - 'python:vcsserver.hooks.pre_push'), + (models.RhodeCodeUi.HOOK_PRETX_PUSH, "python:vcsserver.hooks.pre_push"), ] for hook, value in to_add: log.info('Adding RhodeCodeUI for hook "%s".', hook) create_or_update_hook(models.RhodeCodeUi, hook, value, _SESSION) - _SESSION().commit() \ No newline at end of file + _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/066_version_4_7_0.py b/rhodecode/lib/dbmigrate/versions/066_version_4_7_0.py index 5b9e90b5..089f1989 100644 --- a/rhodecode/lib/dbmigrate/versions/066_version_4_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/066_version_4_7_0.py @@ -29,18 +29,15 @@ def upgrade(migrate_engine): context = MigrationContext.configure(migrate_engine.connect()) op = Operations(context) - existing_indexes = _get_indexes_list( - migrate_engine, db_4_7_0_0.UserApiKeys.__tablename__) + existing_indexes = _get_indexes_list(migrate_engine, db_4_7_0_0.UserApiKeys.__tablename__) - names = [idx['name'] for idx in existing_indexes] + names = [idx["name"] for idx in existing_indexes] with op.batch_alter_table(db_4_7_0_0.UserApiKeys.__tablename__) as batch_op: - if 'uak_api_key_idx' not in names: - batch_op.create_index( - 'uak_api_key_idx', ['api_key']) - if 'uak_api_key_expires_idx' not in names: - batch_op.create_index( - 'uak_api_key_expires_idx', ['api_key', 'expires']) + if "uak_api_key_idx" not in names: + batch_op.create_index("uak_api_key_idx", ["api_key"]) + if "uak_api_key_expires_idx" not in names: + batch_op.create_index("uak_api_key_expires_idx", ["api_key", "expires"]) # issue fixups fixups(db_4_7_0_0, meta.Session) diff --git a/rhodecode/lib/dbmigrate/versions/067_version_4_7_0.py b/rhodecode/lib/dbmigrate/versions/067_version_4_7_0.py index 7b5866e3..f02ddeb1 100644 --- a/rhodecode/lib/dbmigrate/versions/067_version_4_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/067_version_4_7_0.py @@ -21,14 +21,12 @@ def upgrade(migrate_engine): auth_token_table = db_4_7_0_0.UserApiKeys.__table__ - repo_id = Column( - 'repo_id', Integer(), ForeignKey('repositories.repo_id'), - nullable=True, unique=None, default=None) + repo_id = Column("repo_id", Integer(), ForeignKey("repositories.repo_id"), nullable=True, unique=None, default=None) repo_id.create(table=auth_token_table) repo_group_id = Column( - 'repo_group_id', Integer(), ForeignKey('groups.group_id'), - nullable=True, unique=None, default=None) + "repo_group_id", Integer(), ForeignKey("groups.group_id"), nullable=True, unique=None, default=None + ) repo_group_id.create(table=auth_token_table) # issue fixups diff --git a/rhodecode/lib/dbmigrate/versions/068_version_4_7_0.py b/rhodecode/lib/dbmigrate/versions/068_version_4_7_0.py index 79791b42..536f947b 100644 --- a/rhodecode/lib/dbmigrate/versions/068_version_4_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/068_version_4_7_0.py @@ -34,7 +34,7 @@ def _migrate_token(db, user): new_auth_token = db.UserApiKeys() new_auth_token.api_key = user.api_key new_auth_token.user_id = user.user_id - new_auth_token.description = 'Migrated Builtin Token' + new_auth_token.description = "Migrated Builtin Token" new_auth_token.role = db.UserApiKeys.ROLE_ALL new_auth_token.expires = -1 return new_auth_token diff --git a/rhodecode/lib/dbmigrate/versions/069_version_4_7_0.py b/rhodecode/lib/dbmigrate/versions/069_version_4_7_0.py index 45f576e1..72c0a9e7 100644 --- a/rhodecode/lib/dbmigrate/versions/069_version_4_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/069_version_4_7_0.py @@ -17,8 +17,7 @@ def upgrade(migrate_engine): # add last_activity user_table = db.User.__table__ - col1 = Column( - 'last_activity', DateTime(timezone=False), nullable=True, unique=None) + col1 = Column("last_activity", DateTime(timezone=False), nullable=True, unique=None) col1.create(table=user_table) diff --git a/rhodecode/lib/dbmigrate/versions/070_version_4_7_0.py b/rhodecode/lib/dbmigrate/versions/070_version_4_7_0.py index ed62105f..dd727e25 100644 --- a/rhodecode/lib/dbmigrate/versions/070_version_4_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/070_version_4_7_0.py @@ -38,7 +38,7 @@ def downgrade(migrate_engine): def _migrate_user(db, user): - last_activity = time_to_datetime(user.user_data.get('last_activity', 0)) + last_activity = time_to_datetime(user.user_data.get("last_activity", 0)) user.last_activity = last_activity return user @@ -50,7 +50,6 @@ def fixups(models, _SESSION): for user in query: migrated_user = _migrate_user(models, user) _SESSION.add(migrated_user) - log.info( - "Migrating last_activity of user '%s'.", safe_str(user.username)) + log.info("Migrating last_activity of user '%s'.", safe_str(user.username)) _SESSION().commit() diff --git a/rhodecode/lib/dbmigrate/versions/071_version_4_7_0.py b/rhodecode/lib/dbmigrate/versions/071_version_4_7_0.py index 0f9d6d4d..e028618f 100644 --- a/rhodecode/lib/dbmigrate/versions/071_version_4_7_0.py +++ b/rhodecode/lib/dbmigrate/versions/071_version_4_7_0.py @@ -24,7 +24,7 @@ def get_by_key(cls, key): def get_repos_location(cls): - return get_by_key(cls, '/').ui_value + return get_by_key(cls, "/").ui_value def upgrade(migrate_engine): @@ -45,17 +45,14 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - repo_store_path = get_repos_location(models.RhodeCodeUi) - _store = os.path.join(repo_store_path, '.cache', 'lfs_store') - notify('Setting lfs_store to:%s' % _store) + _store = os.path.join(repo_store_path, ".cache", "lfs_store") + notify("Setting lfs_store to:%s" % _store) - if not models.RhodeCodeUi.query().filter( - models.RhodeCodeUi.ui_key == 'store_location').scalar(): + if not models.RhodeCodeUi.query().filter(models.RhodeCodeUi.ui_key == "store_location").scalar(): lfsstore = models.RhodeCodeUi() - lfsstore.ui_section = 'vcs_git_lfs' - lfsstore.ui_key = 'store_location' + lfsstore.ui_section = "vcs_git_lfs" + lfsstore.ui_key = "store_location" lfsstore.ui_value = _store _SESSION().add(lfsstore) _SESSION().commit() - diff --git a/rhodecode/lib/dbmigrate/versions/072_version_4_8_0.py b/rhodecode/lib/dbmigrate/versions/072_version_4_8_0.py index bd54b8a1..fd0ef577 100644 --- a/rhodecode/lib/dbmigrate/versions/072_version_4_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/072_version_4_8_0.py @@ -24,7 +24,7 @@ def get_by_key(cls, key): def get_repos_location(cls): - return get_by_key(cls, '/').ui_value + return get_by_key(cls, "/").ui_value def upgrade(migrate_engine): @@ -38,13 +38,13 @@ def upgrade(migrate_engine): # add last_activity user_log_table = db.UserLog.__table__ - user_data = Column('user_data_json', db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + user_data = Column("user_data_json", db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) user_data.create(table=user_log_table) - version = Column("version", String(255), nullable=True, default='v2') + version = Column("version", String(255), nullable=True, default="v2") version.create(table=user_log_table) - action_data = Column('action_data_json', db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + action_data = Column("action_data_json", db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) action_data.create(table=user_log_table) # issue fixups @@ -58,4 +58,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - diff --git a/rhodecode/lib/dbmigrate/versions/073_version_4_8_0.py b/rhodecode/lib/dbmigrate/versions/073_version_4_8_0.py index 6928cf0e..ecc8756e 100644 --- a/rhodecode/lib/dbmigrate/versions/073_version_4_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/073_version_4_8_0.py @@ -13,7 +13,7 @@ def get_by_key(cls, key): def create_or_update_hook(cls, key, val, SESSION): new_ui = get_by_key(cls, key) or cls() - new_ui.ui_section = 'hooks' + new_ui.ui_section = "hooks" new_ui.ui_active = True new_ui.ui_key = key new_ui.ui_value = val @@ -39,21 +39,16 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - - cleanup_if_present = ( - 'pushkey.key_push', - ) + cleanup_if_present = ("pushkey.key_push",) for hook in cleanup_if_present: - ui_cfg = models.RhodeCodeUi.query().filter( - models.RhodeCodeUi.ui_key == hook).scalar() + ui_cfg = models.RhodeCodeUi.query().filter(models.RhodeCodeUi.ui_key == hook).scalar() if ui_cfg is not None: log.info('Removing RhodeCodeUI for hook "%s".', hook) _SESSION().delete(ui_cfg) to_add = [ - ('pushkey.key_push', - 'python:vcsserver.hooks.key_push'), + ("pushkey.key_push", "python:vcsserver.hooks.key_push"), ] for hook, value in to_add: diff --git a/rhodecode/lib/dbmigrate/versions/074_version_4_8_0.py b/rhodecode/lib/dbmigrate/versions/074_version_4_8_0.py index 7148172f..fab33365 100644 --- a/rhodecode/lib/dbmigrate/versions/074_version_4_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/074_version_4_8_0.py @@ -17,12 +17,10 @@ def upgrade(migrate_engine): repo_review_rule_table = db.RepoReviewRule.__table__ - forbid_author_to_review = Column( - "forbid_author_to_review", Boolean(), nullable=True, default=False) + forbid_author_to_review = Column("forbid_author_to_review", Boolean(), nullable=True, default=False) forbid_author_to_review.create(table=repo_review_rule_table) - forbid_adding_reviewers = Column( - "forbid_adding_reviewers", Boolean(), nullable=True, default=False) + forbid_adding_reviewers = Column("forbid_adding_reviewers", Boolean(), nullable=True, default=False) forbid_adding_reviewers.create(table=repo_review_rule_table) fixups(db, meta.Session) diff --git a/rhodecode/lib/dbmigrate/versions/075_version_4_8_0.py b/rhodecode/lib/dbmigrate/versions/075_version_4_8_0.py index 199aed11..3174f51d 100644 --- a/rhodecode/lib/dbmigrate/versions/075_version_4_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/075_version_4_8_0.py @@ -18,12 +18,10 @@ def upgrade(migrate_engine): repo_review_rule_user_table = db.RepoReviewRuleUser.__table__ repo_review_rule_user_group_table = db.RepoReviewRuleUserGroup.__table__ - mandatory_user = Column( - "mandatory", Boolean(), nullable=True, default=False) + mandatory_user = Column("mandatory", Boolean(), nullable=True, default=False) mandatory_user.create(table=repo_review_rule_user_table) - mandatory_user_group = Column( - "mandatory", Boolean(), nullable=True, default=False) + mandatory_user_group = Column("mandatory", Boolean(), nullable=True, default=False) mandatory_user_group.create(table=repo_review_rule_user_group_table) fixups(db, meta.Session) diff --git a/rhodecode/lib/dbmigrate/versions/076_version_4_8_0.py b/rhodecode/lib/dbmigrate/versions/076_version_4_8_0.py index bff46235..466beab2 100644 --- a/rhodecode/lib/dbmigrate/versions/076_version_4_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/076_version_4_8_0.py @@ -17,8 +17,7 @@ def upgrade(migrate_engine): pull_request_reviewers = db.PullRequestReviewers.__table__ - mandatory = Column( - "mandatory", Boolean(), nullable=True, default=False) + mandatory = Column("mandatory", Boolean(), nullable=True, default=False) mandatory.create(table=pull_request_reviewers) fixups(db, meta.Session) diff --git a/rhodecode/lib/dbmigrate/versions/077_version_4_8_0.py b/rhodecode/lib/dbmigrate/versions/077_version_4_8_0.py index bb9eb868..a3fb62bc 100644 --- a/rhodecode/lib/dbmigrate/versions/077_version_4_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/077_version_4_8_0.py @@ -18,14 +18,10 @@ def upgrade(migrate_engine): pull_request = db.PullRequest.__table__ pull_request_version = db.PullRequestVersion.__table__ - reviewer_data_1 = Column( - 'reviewer_data_json', - db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + reviewer_data_1 = Column("reviewer_data_json", db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) reviewer_data_1.create(table=pull_request) - reviewer_data_2 = Column( - 'reviewer_data_json', - db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + reviewer_data_2 = Column("reviewer_data_json", db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) reviewer_data_2.create(table=pull_request_version) fixups(db, meta.Session) diff --git a/rhodecode/lib/dbmigrate/versions/078_version_4_8_0.py b/rhodecode/lib/dbmigrate/versions/078_version_4_8_0.py index fa336578..cfbce7f8 100644 --- a/rhodecode/lib/dbmigrate/versions/078_version_4_8_0.py +++ b/rhodecode/lib/dbmigrate/versions/078_version_4_8_0.py @@ -17,8 +17,7 @@ def upgrade(migrate_engine): repo_review_rule_table = db.RepoReviewRule.__table__ - forbid_commit_author_to_review = Column( - "forbid_commit_author_to_review", Boolean(), nullable=True, default=False) + forbid_commit_author_to_review = Column("forbid_commit_author_to_review", Boolean(), nullable=True, default=False) forbid_commit_author_to_review.create(table=repo_review_rule_table) fixups(db, meta.Session) diff --git a/rhodecode/lib/dbmigrate/versions/079_version_4_9_0.py b/rhodecode/lib/dbmigrate/versions/079_version_4_9_0.py index b3034783..d23185ff 100644 --- a/rhodecode/lib/dbmigrate/versions/079_version_4_9_0.py +++ b/rhodecode/lib/dbmigrate/versions/079_version_4_9_0.py @@ -19,8 +19,8 @@ def upgrade(migrate_engine): repo_group_table = db.RepoGroup.__table__ updated_on = Column( - 'updated_on', DateTime(timezone=False), nullable=True, unique=None, - default=datetime.datetime.now) + "updated_on", DateTime(timezone=False), nullable=True, unique=None, default=datetime.datetime.now + ) updated_on.create(table=repo_group_table) fixups(db, meta.Session) diff --git a/rhodecode/lib/dbmigrate/versions/081_version_4_10_0.py b/rhodecode/lib/dbmigrate/versions/081_version_4_10_0.py index 2be151be..54fdb27b 100644 --- a/rhodecode/lib/dbmigrate/versions/081_version_4_10_0.py +++ b/rhodecode/lib/dbmigrate/versions/081_version_4_10_0.py @@ -21,14 +21,12 @@ def upgrade(migrate_engine): _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_4_9_0_0 - if migrate_engine.name in ['mysql']: - + if migrate_engine.name in ["mysql"]: context = MigrationContext.configure(migrate_engine.connect()) op = Operations(context) user_log_table = db_4_9_0_0.UserLog.__table__ with op.batch_alter_table(user_log_table.name) as batch_op: - action_data_json = user_log_table.columns.action_data_json user_data_json = user_log_table.columns.user_data_json @@ -46,5 +44,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/082_version_4_11_0.py b/rhodecode/lib/dbmigrate/versions/082_version_4_11_0.py index d8bc8af2..768d52e0 100644 --- a/rhodecode/lib/dbmigrate/versions/082_version_4_11_0.py +++ b/rhodecode/lib/dbmigrate/versions/082_version_4_11_0.py @@ -15,6 +15,7 @@ def upgrade(migrate_engine): """ _reset_base(migrate_engine) from rhodecode.lib.dbmigrate.schema import db_4_11_0_0 + db_4_11_0_0.ScheduleEntry().__table__.create() # issue fixups @@ -28,5 +29,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/083_version_4_11_0.py b/rhodecode/lib/dbmigrate/versions/083_version_4_11_0.py index fec87d5a..b9a1bdd4 100644 --- a/rhodecode/lib/dbmigrate/versions/083_version_4_11_0.py +++ b/rhodecode/lib/dbmigrate/versions/083_version_4_11_0.py @@ -19,11 +19,11 @@ def upgrade(migrate_engine): review_rule_table = db.RepoReviewRule.__table__ target_branch_pattern = Column( - "target_branch_pattern", - UnicodeText().with_variant(UnicodeText(255), 'mysql'), default=u'*') + "target_branch_pattern", UnicodeText().with_variant(UnicodeText(255), "mysql"), default="*" + ) target_branch_pattern.create(table=review_rule_table) - review_rule_name = Column('review_rule_name', String(255)) + review_rule_name = Column("review_rule_name", String(255)) review_rule_name.create(table=review_rule_table) # issue fixups @@ -37,5 +37,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/084_version_4_11_0.py b/rhodecode/lib/dbmigrate/versions/084_version_4_11_0.py index 7ebd3ebc..adf10c48 100644 --- a/rhodecode/lib/dbmigrate/versions/084_version_4_11_0.py +++ b/rhodecode/lib/dbmigrate/versions/084_version_4_11_0.py @@ -18,9 +18,7 @@ def upgrade(migrate_engine): reviewers_table = db.PullRequestReviewers.__table__ - rule_data = Column( - 'rule_data_json', - db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + rule_data = Column("rule_data_json", db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) rule_data.create(table=reviewers_table) # issue fixups @@ -34,5 +32,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/085_version_4_11_0.py b/rhodecode/lib/dbmigrate/versions/085_version_4_11_0.py index f34352d6..c1a82377 100644 --- a/rhodecode/lib/dbmigrate/versions/085_version_4_11_0.py +++ b/rhodecode/lib/dbmigrate/versions/085_version_4_11_0.py @@ -18,8 +18,7 @@ def upgrade(migrate_engine): user_group_review_table = db.RepoReviewRuleUserGroup.__table__ - vote_rule = Column("vote_rule", Integer(), nullable=True, - default=-1) + vote_rule = Column("vote_rule", Integer(), nullable=True, default=-1) vote_rule.create(table=user_group_review_table) # issue fixups @@ -33,5 +32,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/086_version_4_12_0.py b/rhodecode/lib/dbmigrate/versions/086_version_4_12_0.py index 22470bb1..9fb24466 100644 --- a/rhodecode/lib/dbmigrate/versions/086_version_4_12_0.py +++ b/rhodecode/lib/dbmigrate/versions/086_version_4_12_0.py @@ -18,9 +18,7 @@ def upgrade(migrate_engine): repository_table = db.Repository.__table__ - push_uri = Column( - "push_uri", db.EncryptedTextValue(), nullable=True, unique=False, - default=None) + push_uri = Column("push_uri", db.EncryptedTextValue(), nullable=True, unique=False, default=None) push_uri.create(table=repository_table) @@ -35,5 +33,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/087_version_4_13_0.py b/rhodecode/lib/dbmigrate/versions/087_version_4_13_0.py index 6af8cebf..675a9ac2 100644 --- a/rhodecode/lib/dbmigrate/versions/087_version_4_13_0.py +++ b/rhodecode/lib/dbmigrate/versions/087_version_4_13_0.py @@ -19,10 +19,10 @@ def upgrade(migrate_engine): pull_request_table = db.PullRequest.__table__ pull_request_version_table = db.PullRequestVersion.__table__ - renderer = Column('description_renderer', Unicode(64), nullable=True) + renderer = Column("description_renderer", Unicode(64), nullable=True) renderer.create(table=pull_request_table) - renderer_ver = Column('description_renderer', Unicode(64), nullable=True) + renderer_ver = Column("description_renderer", Unicode(64), nullable=True) renderer_ver.create(table=pull_request_version_table) # issue fixups @@ -36,5 +36,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/088_version_4_13_0.py b/rhodecode/lib/dbmigrate/versions/088_version_4_13_0.py index e1215636..eaacfa76 100644 --- a/rhodecode/lib/dbmigrate/versions/088_version_4_13_0.py +++ b/rhodecode/lib/dbmigrate/versions/088_version_4_13_0.py @@ -7,8 +7,7 @@ from sqlalchemy.dialects.mysql import LONGTEXT from alembic.migration import MigrationContext from alembic.operations import Operations -from rhodecode.lib.dbmigrate.utils import create_default_permissions, \ - create_default_object_permission +from rhodecode.lib.dbmigrate.utils import create_default_permissions, create_default_object_permission from rhodecode.model import meta from rhodecode.lib.dbmigrate.versions import _reset_base, notify @@ -35,12 +34,11 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): # create default permissions create_default_permissions(_SESSION, models) - log.info('created default global permissions definitions') + log.info("created default global permissions definitions") _SESSION().commit() # # fix default object permissions # create_default_object_permission(_SESSION, models) - log.info('created default permission') + log.info("created default permission") _SESSION().commit() - diff --git a/rhodecode/lib/dbmigrate/versions/089_version_4_13_0.py b/rhodecode/lib/dbmigrate/versions/089_version_4_13_0.py index d456249d..ed36c2d7 100644 --- a/rhodecode/lib/dbmigrate/versions/089_version_4_13_0.py +++ b/rhodecode/lib/dbmigrate/versions/089_version_4_13_0.py @@ -35,5 +35,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/090_version_4_13_0.py b/rhodecode/lib/dbmigrate/versions/090_version_4_13_0.py index aedaf003..ce9fe631 100644 --- a/rhodecode/lib/dbmigrate/versions/090_version_4_13_0.py +++ b/rhodecode/lib/dbmigrate/versions/090_version_4_13_0.py @@ -2,8 +2,7 @@ import logging from sqlalchemy import * -from rhodecode.lib.dbmigrate.utils import ( - create_default_object_permission, create_default_permissions) +from rhodecode.lib.dbmigrate.utils import create_default_object_permission, create_default_permissions from rhodecode.model import meta from rhodecode.lib.dbmigrate.versions import _reset_base, notify @@ -31,13 +30,11 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): # create default permissions create_default_permissions(_SESSION, models) - log.info('created default global permissions definitions') + log.info("created default global permissions definitions") _SESSION().commit() # fix default object permissions create_default_object_permission(_SESSION, models) - log.info('created default permission') + log.info("created default permission") _SESSION().commit() - - diff --git a/rhodecode/lib/dbmigrate/versions/091_version_4_14_0.py b/rhodecode/lib/dbmigrate/versions/091_version_4_14_0.py index 148c56fe..b1d39aa6 100644 --- a/rhodecode/lib/dbmigrate/versions/091_version_4_14_0.py +++ b/rhodecode/lib/dbmigrate/versions/091_version_4_14_0.py @@ -18,7 +18,7 @@ def upgrade(migrate_engine): repository_table = db.Repository.__table__ - archived = Column('archived', Boolean(), nullable=True) + archived = Column("archived", Boolean(), nullable=True) archived.create(table=repository_table) # issue fixups @@ -32,5 +32,3 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): pass - - diff --git a/rhodecode/lib/dbmigrate/versions/093_version_4_16_0.py b/rhodecode/lib/dbmigrate/versions/093_version_4_16_0.py index 2bef06c4..29972d84 100644 --- a/rhodecode/lib/dbmigrate/versions/093_version_4_16_0.py +++ b/rhodecode/lib/dbmigrate/versions/093_version_4_16_0.py @@ -27,15 +27,12 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): # move the builtin token to external tokens - log.info('Updating pull request pull_request_state to %s', - models.PullRequest.STATE_CREATED) + log.info("Updating pull request pull_request_state to %s", models.PullRequest.STATE_CREATED) qry = _SESSION().query(models.PullRequest) qry.update({"pull_request_state": models.PullRequest.STATE_CREATED}) _SESSION().commit() - log.info('Updating pull_request_version pull_request_state to %s', - models.PullRequest.STATE_CREATED) + log.info("Updating pull_request_version pull_request_state to %s", models.PullRequest.STATE_CREATED) qry = _SESSION().query(models.PullRequestVersion) qry.update({"pull_request_state": models.PullRequest.STATE_CREATED}) _SESSION().commit() - diff --git a/rhodecode/lib/dbmigrate/versions/096_version_4_17_0.py b/rhodecode/lib/dbmigrate/versions/096_version_4_17_0.py index bf85e694..bd64a9cc 100644 --- a/rhodecode/lib/dbmigrate/versions/096_version_4_17_0.py +++ b/rhodecode/lib/dbmigrate/versions/096_version_4_17_0.py @@ -1,5 +1,3 @@ - - import logging from alembic.migration import MigrationContext @@ -32,8 +30,7 @@ def upgrade(migrate_engine): repo_group = db_4_16_0_2.RepoGroup.__table__ with op.batch_alter_table(repo_group.name) as batch_op: - batch_op.add_column( - Column("repo_group_name_hash", String(1024), nullable=True, unique=False)) + batch_op.add_column(Column("repo_group_name_hash", String(1024), nullable=True, unique=False)) _generate_repo_group_name_hashes(db_4_16_0_2, op, meta.Session) @@ -47,9 +44,7 @@ def _generate_repo_group_name_hashes(models, op, session): for repo_group in repo_groups: print(safe_str(repo_group.group_name)) hash_ = RepoGroup.hash_repo_group_name(repo_group.group_name) - params = {'hash': hash_, 'id': repo_group.group_id} - query = text( - 'UPDATE groups SET repo_group_name_hash = :hash' - ' WHERE group_id = :id').bindparams(**params) + params = {"hash": hash_, "id": repo_group.group_id} + query = text("UPDATE groups SET repo_group_name_hash = :hash WHERE group_id = :id").bindparams(**params) op.execute(query) session().commit() diff --git a/rhodecode/lib/dbmigrate/versions/097_version_4_17_0.py b/rhodecode/lib/dbmigrate/versions/097_version_4_17_0.py index 180157f3..838607ae 100644 --- a/rhodecode/lib/dbmigrate/versions/097_version_4_17_0.py +++ b/rhodecode/lib/dbmigrate/versions/097_version_4_17_0.py @@ -1,5 +1,3 @@ - - import logging from alembic.migration import MigrationContext diff --git a/rhodecode/lib/dbmigrate/versions/098_version_4_17_0.py b/rhodecode/lib/dbmigrate/versions/098_version_4_17_0.py index f539ce17..4b66cce8 100644 --- a/rhodecode/lib/dbmigrate/versions/098_version_4_17_0.py +++ b/rhodecode/lib/dbmigrate/versions/098_version_4_17_0.py @@ -1,5 +1,3 @@ - - import logging from alembic.migration import MigrationContext @@ -29,8 +27,7 @@ def upgrade(migrate_engine): repo_group = db_4_16_0_2.RepoGroup.__table__ with op.batch_alter_table(repo_group.name) as batch_op: - batch_op.add_column( - Column("changeset_cache", LargeBinary(1024), nullable=True)) + batch_op.add_column(Column("changeset_cache", LargeBinary(1024), nullable=True)) def downgrade(migrate_engine): diff --git a/rhodecode/lib/dbmigrate/versions/099_version_4_18_0.py b/rhodecode/lib/dbmigrate/versions/099_version_4_18_0.py index 7024102c..ec50907e 100644 --- a/rhodecode/lib/dbmigrate/versions/099_version_4_18_0.py +++ b/rhodecode/lib/dbmigrate/versions/099_version_4_18_0.py @@ -1,5 +1,3 @@ - - import logging from alembic.migration import MigrationContext @@ -29,8 +27,7 @@ def upgrade(migrate_engine): cache_key = db_4_16_0_2.CacheKey.__table__ with op.batch_alter_table(cache_key.name) as batch_op: - batch_op.add_column( - Column("cache_state_uid", String(255), nullable=True, unique=None, default=None)) + batch_op.add_column(Column("cache_state_uid", String(255), nullable=True, unique=None, default=None)) def downgrade(migrate_engine): diff --git a/rhodecode/lib/dbmigrate/versions/100_version_4_18_0.py b/rhodecode/lib/dbmigrate/versions/100_version_4_18_0.py index 37083fe7..25f1ed91 100644 --- a/rhodecode/lib/dbmigrate/versions/100_version_4_18_0.py +++ b/rhodecode/lib/dbmigrate/versions/100_version_4_18_0.py @@ -1,5 +1,3 @@ - - import logging from alembic.migration import MigrationContext @@ -29,8 +27,7 @@ def upgrade(migrate_engine): cache_key = db_4_16_0_2.FileStore.__table__ with op.batch_alter_table(cache_key.name) as batch_op: - batch_op.add_column( - Column('hidden', Boolean(), nullable=True, default=False)) + batch_op.add_column(Column("hidden", Boolean(), nullable=True, default=False)) def downgrade(migrate_engine): diff --git a/rhodecode/lib/dbmigrate/versions/101_version_4_18_0.py b/rhodecode/lib/dbmigrate/versions/101_version_4_18_0.py index 09888632..8b85dbf1 100644 --- a/rhodecode/lib/dbmigrate/versions/101_version_4_18_0.py +++ b/rhodecode/lib/dbmigrate/versions/101_version_4_18_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * diff --git a/rhodecode/lib/dbmigrate/versions/102_version_4_18_0.py b/rhodecode/lib/dbmigrate/versions/102_version_4_18_0.py index 386be5d0..96a868e5 100644 --- a/rhodecode/lib/dbmigrate/versions/102_version_4_18_0.py +++ b/rhodecode/lib/dbmigrate/versions/102_version_4_18_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * diff --git a/rhodecode/lib/dbmigrate/versions/103_version_4_18_0.py b/rhodecode/lib/dbmigrate/versions/103_version_4_18_0.py index 13c34c4e..3e3f7d93 100644 --- a/rhodecode/lib/dbmigrate/versions/103_version_4_18_0.py +++ b/rhodecode/lib/dbmigrate/versions/103_version_4_18_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -30,7 +28,7 @@ def upgrade(migrate_engine): user = db_4_18_0_1.User.__table__ with op.batch_alter_table(user.name) as batch_op: - batch_op.add_column(Column('description', UnicodeText().with_variant(UnicodeText(1024), 'mysql'))) + batch_op.add_column(Column("description", UnicodeText().with_variant(UnicodeText(1024), "mysql"))) def downgrade(migrate_engine): diff --git a/rhodecode/lib/dbmigrate/versions/104_version_4_19_0.py b/rhodecode/lib/dbmigrate/versions/104_version_4_19_0.py index b9790074..f9f781fb 100644 --- a/rhodecode/lib/dbmigrate/versions/104_version_4_19_0.py +++ b/rhodecode/lib/dbmigrate/versions/104_version_4_19_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -30,16 +28,12 @@ def upgrade(migrate_engine): pull_requests = db.PullRequest.__table__ with op.batch_alter_table(pull_requests.name) as batch_op: - new_column = Column( - 'last_merge_metadata', - db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + new_column = Column("last_merge_metadata", db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) batch_op.add_column(new_column) pull_request_version = db.PullRequestVersion.__table__ with op.batch_alter_table(pull_request_version.name) as batch_op: - new_column = Column( - 'last_merge_metadata', - db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) + new_column = Column("last_merge_metadata", db.JsonType(dialect_map=dict(mysql=UnicodeText(16384)))) batch_op.add_column(new_column) diff --git a/rhodecode/lib/dbmigrate/versions/105_version_4_19_0.py b/rhodecode/lib/dbmigrate/versions/105_version_4_19_0.py index 23853fce..78da3181 100644 --- a/rhodecode/lib/dbmigrate/versions/105_version_4_19_0.py +++ b/rhodecode/lib/dbmigrate/versions/105_version_4_19_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * diff --git a/rhodecode/lib/dbmigrate/versions/106_version_4_19_0.py b/rhodecode/lib/dbmigrate/versions/106_version_4_19_0.py index 66bbd486..841f6a8f 100644 --- a/rhodecode/lib/dbmigrate/versions/106_version_4_19_0.py +++ b/rhodecode/lib/dbmigrate/versions/106_version_4_19_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -30,7 +28,7 @@ def upgrade(migrate_engine): comments = db.ChangesetComment.__table__ with op.batch_alter_table(comments.name) as batch_op: - new_column = Column('immutable_state', Unicode(128), nullable=True) + new_column = Column("immutable_state", Unicode(128), nullable=True) batch_op.add_column(new_column) diff --git a/rhodecode/lib/dbmigrate/versions/107_version_4_19_0.py b/rhodecode/lib/dbmigrate/versions/107_version_4_19_0.py index 51e2cd1b..104d9932 100644 --- a/rhodecode/lib/dbmigrate/versions/107_version_4_19_0.py +++ b/rhodecode/lib/dbmigrate/versions/107_version_4_19_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -29,12 +27,12 @@ def upgrade(migrate_engine): pull_requests = db.PullRequest.__table__ with op.batch_alter_table(pull_requests.name) as batch_op: - new_column = Column('common_ancestor_id', Unicode(255), nullable=True) + new_column = Column("common_ancestor_id", Unicode(255), nullable=True) batch_op.add_column(new_column) pull_request_version = db.PullRequestVersion.__table__ with op.batch_alter_table(pull_request_version.name) as batch_op: - new_column = Column('common_ancestor_id', Unicode(255), nullable=True) + new_column = Column("common_ancestor_id", Unicode(255), nullable=True) batch_op.add_column(new_column) diff --git a/rhodecode/lib/dbmigrate/versions/108_version_4_19_1.py b/rhodecode/lib/dbmigrate/versions/108_version_4_19_1.py index 467c6e39..7dd63af4 100644 --- a/rhodecode/lib/dbmigrate/versions/108_version_4_19_1.py +++ b/rhodecode/lib/dbmigrate/versions/108_version_4_19_1.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * diff --git a/rhodecode/lib/dbmigrate/versions/109_version_4_21_1.py b/rhodecode/lib/dbmigrate/versions/109_version_4_21_1.py index 290e4425..916e501f 100644 --- a/rhodecode/lib/dbmigrate/versions/109_version_4_21_1.py +++ b/rhodecode/lib/dbmigrate/versions/109_version_4_21_1.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -28,7 +26,7 @@ def upgrade(migrate_engine): table = db.PullRequestReviewers.__table__ with op.batch_alter_table(table.name) as batch_op: - new_column = Column('role', Unicode(255), nullable=True) + new_column = Column("role", Unicode(255), nullable=True) batch_op.add_column(new_column) _fill_reviewers_role(db, op, meta.Session) @@ -44,9 +42,7 @@ def fixups(models, _SESSION): def _fill_reviewers_role(models, op, session): - params = {'role': 'reviewer'} - query = text( - 'UPDATE pull_request_reviewers SET role = :role' - ).bindparams(**params) + params = {"role": "reviewer"} + query = text("UPDATE pull_request_reviewers SET role = :role").bindparams(**params) op.execute(query) session().commit() diff --git a/rhodecode/lib/dbmigrate/versions/110_version_4_22_0.py b/rhodecode/lib/dbmigrate/versions/110_version_4_22_0.py index 9bd64f12..ccb82079 100644 --- a/rhodecode/lib/dbmigrate/versions/110_version_4_22_0.py +++ b/rhodecode/lib/dbmigrate/versions/110_version_4_22_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -28,14 +26,14 @@ def upgrade(migrate_engine): table = db.RepoReviewRuleUser.__table__ with op.batch_alter_table(table.name) as batch_op: - new_column = Column('role', Unicode(255), nullable=True) + new_column = Column("role", Unicode(255), nullable=True) batch_op.add_column(new_column) _fill_rule_user_role(op, meta.Session) table = db.RepoReviewRuleUserGroup.__table__ with op.batch_alter_table(table.name) as batch_op: - new_column = Column('role', Unicode(255), nullable=True) + new_column = Column("role", Unicode(255), nullable=True) batch_op.add_column(new_column) _fill_rule_user_group_role(op, meta.Session) @@ -51,18 +49,14 @@ def fixups(models, _SESSION): def _fill_rule_user_role(op, session): - params = {'role': 'reviewer'} - query = text( - 'UPDATE repo_review_rules_users SET role = :role' - ).bindparams(**params) + params = {"role": "reviewer"} + query = text("UPDATE repo_review_rules_users SET role = :role").bindparams(**params) op.execute(query) session().commit() def _fill_rule_user_group_role(op, session): - params = {'role': 'reviewer'} - query = text( - 'UPDATE repo_review_rules_users_groups SET role = :role' - ).bindparams(**params) + params = {"role": "reviewer"} + query = text("UPDATE repo_review_rules_users_groups SET role = :role").bindparams(**params) op.execute(query) session().commit() diff --git a/rhodecode/lib/dbmigrate/versions/111_version_4_23_0.py b/rhodecode/lib/dbmigrate/versions/111_version_4_23_0.py index ceef07a4..454cc1bd 100644 --- a/rhodecode/lib/dbmigrate/versions/111_version_4_23_0.py +++ b/rhodecode/lib/dbmigrate/versions/111_version_4_23_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -28,7 +26,7 @@ def upgrade(migrate_engine): table = db.ChangesetComment.__table__ with op.batch_alter_table(table.name) as batch_op: - new_column = Column('draft', Boolean(), nullable=True) + new_column = Column("draft", Boolean(), nullable=True) batch_op.add_column(new_column) _set_default_as_non_draft(op, meta.Session) @@ -44,10 +42,7 @@ def fixups(models, _SESSION): def _set_default_as_non_draft(op, session): - params = {'draft': False} - query = text( - 'UPDATE changeset_comments SET draft = :draft' - ).bindparams(**params) + params = {"draft": False} + query = text("UPDATE changeset_comments SET draft = :draft").bindparams(**params) op.execute(query) session().commit() - diff --git a/rhodecode/lib/dbmigrate/versions/112_version_4_23_0.py b/rhodecode/lib/dbmigrate/versions/112_version_4_23_0.py index 9b8cdb87..bcb9993b 100644 --- a/rhodecode/lib/dbmigrate/versions/112_version_4_23_0.py +++ b/rhodecode/lib/dbmigrate/versions/112_version_4_23_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -28,11 +26,10 @@ def upgrade(migrate_engine): table = db.RepoReviewRule.__table__ with op.batch_alter_table(table.name) as batch_op: - - new_column = Column('pr_author', UnicodeText().with_variant(UnicodeText(255), 'mysql'), nullable=True) + new_column = Column("pr_author", UnicodeText().with_variant(UnicodeText(255), "mysql"), nullable=True) batch_op.add_column(new_column) - new_column = Column('commit_author', UnicodeText().with_variant(UnicodeText(255), 'mysql'), nullable=True) + new_column = Column("commit_author", UnicodeText().with_variant(UnicodeText(255), "mysql"), nullable=True) batch_op.add_column(new_column) _migrate_review_flags_to_new_cols(op, meta.Session) @@ -48,31 +45,26 @@ def fixups(models, _SESSION): def _migrate_review_flags_to_new_cols(op, session): - # set defaults for pr_author - query = text( - 'UPDATE repo_review_rules SET pr_author = :val' - ).bindparams(val='no_rule') + query = text("UPDATE repo_review_rules SET pr_author = :val").bindparams(val="no_rule") op.execute(query) # set defaults for commit_author - query = text( - 'UPDATE repo_review_rules SET commit_author = :val' - ).bindparams(val='no_rule') + query = text("UPDATE repo_review_rules SET commit_author = :val").bindparams(val="no_rule") op.execute(query) session().commit() # now change the flags to forbid based on # forbid_author_to_review, forbid_commit_author_to_review - query = text( - 'UPDATE repo_review_rules SET pr_author = :val WHERE forbid_author_to_review = TRUE' - ).bindparams(val='forbid_pr_author') + query = text("UPDATE repo_review_rules SET pr_author = :val WHERE forbid_author_to_review = TRUE").bindparams( + val="forbid_pr_author" + ) op.execute(query) query = text( - 'UPDATE repo_review_rules SET commit_author = :val WHERE forbid_commit_author_to_review = TRUE' - ).bindparams(val='forbid_commit_author') + "UPDATE repo_review_rules SET commit_author = :val WHERE forbid_commit_author_to_review = TRUE" + ).bindparams(val="forbid_commit_author") op.execute(query) session().commit() diff --git a/rhodecode/lib/dbmigrate/versions/113_version_4_24_0.py b/rhodecode/lib/dbmigrate/versions/113_version_4_24_0.py index f6e44f67..0ee60a79 100644 --- a/rhodecode/lib/dbmigrate/versions/113_version_4_24_0.py +++ b/rhodecode/lib/dbmigrate/versions/113_version_4_24_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * @@ -39,7 +37,7 @@ def fixups(models, _SESSION): def get_by_name(cls, key): return cls.query().filter(cls.app_settings_name == key).scalar() - def create_or_update(cls, key, val=Optional(''), type_=Optional('unicode')): + def create_or_update(cls, key, val=Optional(""), type_=Optional("unicode")): res = get_by_name(cls, key) if not res: val = Optional.extract(val) @@ -56,9 +54,8 @@ def fixups(models, _SESSION): return res clone_uri_tmpl = models.Repository.DEFAULT_CLONE_URI_ID - print('settings new clone by url template to %s' % clone_uri_tmpl) + print("settings new clone by url template to %s" % clone_uri_tmpl) - sett = create_or_update(models.RhodeCodeSetting, - 'clone_uri_id_tmpl', clone_uri_tmpl, 'unicode') + sett = create_or_update(models.RhodeCodeSetting, "clone_uri_id_tmpl", clone_uri_tmpl, "unicode") _SESSION().add(sett) _SESSION.commit() diff --git a/rhodecode/lib/dbmigrate/versions/114_version_4_28_0.py b/rhodecode/lib/dbmigrate/versions/114_version_4_28_0.py index 2e890957..7d0a99da 100644 --- a/rhodecode/lib/dbmigrate/versions/114_version_4_28_0.py +++ b/rhodecode/lib/dbmigrate/versions/114_version_4_28_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * from sqlalchemy.engine import reflection @@ -34,15 +32,13 @@ def upgrade(migrate_engine): context = MigrationContext.configure(migrate_engine.connect()) op = Operations(context) - existing_indexes = _get_indexes_list( - migrate_engine, db_4_20_0_0.CacheKey.__tablename__) + existing_indexes = _get_indexes_list(migrate_engine, db_4_20_0_0.CacheKey.__tablename__) - names = [idx['name'] for idx in existing_indexes] + names = [idx["name"] for idx in existing_indexes] with op.batch_alter_table(db_4_20_0_0.CacheKey.__tablename__) as batch_op: - if 'cache_args_idx' not in names: - batch_op.create_index( - 'cache_args_idx', ['cache_args']) + if "cache_args_idx" not in names: + batch_op.create_index("cache_args_idx", ["cache_args"]) def downgrade(migrate_engine): diff --git a/rhodecode/lib/dbmigrate/versions/115_version_5_1_0.py b/rhodecode/lib/dbmigrate/versions/115_version_5_1_0.py index 90de0691..ae0936f4 100644 --- a/rhodecode/lib/dbmigrate/versions/115_version_5_1_0.py +++ b/rhodecode/lib/dbmigrate/versions/115_version_5_1_0.py @@ -1,5 +1,3 @@ - - import logging from sqlalchemy import * from sqlalchemy.engine import reflection @@ -35,19 +33,17 @@ def downgrade(migrate_engine): def fixups(models, _SESSION): - for db_repo in _SESSION.query(models.Repository).all(): - try: config = db_repo._config - config.set('extensions', 'largefiles', '') + config.set("extensions", "largefiles", "") scm = db_repo.scm_instance(cache=False, config=config, vcs_full_cache=False) if scm: - print(f'installing hook for repo: {db_repo}') + print(f"installing hook for repo: {db_repo}") scm.install_hooks(force=True) del scm # force GC del config except Exception as e: print(e) - print('continue...') + print("continue...") diff --git a/rhodecode/lib/dbmigrate/versions/__init__.py b/rhodecode/lib/dbmigrate/versions/__init__.py index 364c1869..748c4941 100644 --- a/rhodecode/lib/dbmigrate/versions/__init__.py +++ b/rhodecode/lib/dbmigrate/versions/__init__.py @@ -35,7 +35,7 @@ def notify(msg, caps=True): Notification for migrations messages """ ml = len(msg) + (4 * 2) - formatted_msg = ('\n%s\n*** %s ***\n%s' % ('*' * ml, msg, '*' * ml)) + formatted_msg = "\n%s\n*** %s ***\n%s" % ("*" * ml, msg, "*" * ml) if caps: formatted_msg = formatted_msg.upper() print(formatted_msg) @@ -49,8 +49,8 @@ def _reset_base(migrate_engine): Base.metadata.bind = migrate_engine # new session and base - #meta.Session = scoped_session(sessionmaker(expire_on_commit=True,)) - #meta.Session.configure(bind=migrate_engine) + # meta.Session = scoped_session(sessionmaker(expire_on_commit=True,)) + # meta.Session.configure(bind=migrate_engine) meta.Base = Base - notify('SQLA BASE RESET !') + notify("SQLA BASE RESET !") diff --git a/rhodecode/lib/diff_match_patch.py b/rhodecode/lib/diff_match_patch.py index 9c073efd..863416db 100644 --- a/rhodecode/lib/diff_match_patch.py +++ b/rhodecode/lib/diff_match_patch.py @@ -170,7 +170,7 @@ class diff_match_patch: diffs = [ (self.DIFF_INSERT, longtext[:i]), (self.DIFF_EQUAL, shorttext), - (self.DIFF_INSERT, longtext[i + len(shorttext):]), + (self.DIFF_INSERT, longtext[i + len(shorttext) :]), ] # Swap insertions for deletions if diff is reversed. if len(text1) > len(text2): @@ -243,7 +243,7 @@ class diff_match_patch: if count_delete >= 1 and count_insert >= 1: # Delete the offending records and add the merged ones. a = self.diff_main(text_delete, text_insert, False, deadline) - diffs[pointer - count_delete - count_insert: pointer] = a + diffs[pointer - count_delete - count_insert : pointer] = a pointer = pointer - count_delete - count_insert + len(a) count_insert = 0 count_delete = 0 @@ -302,9 +302,7 @@ class diff_match_patch: else: x1 = v1[k1_offset - 1] + 1 y1 = x1 - k1 - while ( - x1 < text1_length and y1 < text2_length and text1[x1] == text2[y1] - ): + while x1 < text1_length and y1 < text2_length and text1[x1] == text2[y1]: x1 += 1 y1 += 1 v1[k1_offset] = x1 @@ -331,11 +329,7 @@ class diff_match_patch: else: x2 = v2[k2_offset - 1] + 1 y2 = x2 - k2 - while ( - x2 < text1_length - and y2 < text2_length - and text1[-x2 - 1] == text2[-y2 - 1] - ): + while x2 < text1_length and y2 < text2_length and text1[-x2 - 1] == text2[-y2 - 1]: x2 += 1 y2 += 1 v2[k2_offset] = x2 @@ -503,10 +497,7 @@ class diff_match_patch: pointermid = pointermax pointerend = 0 while pointermin < pointermid: - if ( - text1[-pointermid : len(text1) - pointerend] - == text2[-pointermid : len(text2) - pointerend] - ): + if text1[-pointermid : len(text1) - pointerend] == text2[-pointermid : len(text2) - pointerend]: pointermin = pointermid pointerend = pointermin else: @@ -602,10 +593,7 @@ class diff_match_patch: prefixLength = self.diff_commonPrefix(longtext[i:], shorttext[j:]) suffixLength = self.diff_commonSuffix(longtext[:i], shorttext[:j]) if len(best_common) < suffixLength + prefixLength: - best_common = ( - shorttext[j - suffixLength : j] - + shorttext[j : j + prefixLength] - ) + best_common = shorttext[j - suffixLength : j] + shorttext[j : j + prefixLength] best_longtext_a = longtext[: i - suffixLength] best_longtext_b = longtext[i + prefixLength :] best_shorttext_a = shorttext[: j - suffixLength] @@ -677,12 +665,8 @@ class diff_match_patch: # sides of it. if ( lastequality - and ( - len(lastequality) <= max(length_insertions1, length_deletions1) - ) - and ( - len(lastequality) <= max(length_insertions2, length_deletions2) - ) + and (len(lastequality) <= max(length_insertions1, length_deletions1)) + and (len(lastequality) <= max(length_insertions2, length_deletions2)) ): # Duplicate record. diffs.insert(equalities[-1], (self.DIFF_DELETE, lastequality)) @@ -720,23 +704,15 @@ class diff_match_patch: # Only extract an overlap if it is as big as the edit ahead or behind it. pointer = 1 while pointer < len(diffs): - if ( - diffs[pointer - 1][0] == self.DIFF_DELETE - and diffs[pointer][0] == self.DIFF_INSERT - ): + if diffs[pointer - 1][0] == self.DIFF_DELETE and diffs[pointer][0] == self.DIFF_INSERT: deletion = diffs[pointer - 1][1] insertion = diffs[pointer][1] overlap_length1 = self.diff_commonOverlap(deletion, insertion) overlap_length2 = self.diff_commonOverlap(insertion, deletion) if overlap_length1 >= overlap_length2: - if ( - overlap_length1 >= len(deletion) / 2.0 - or overlap_length1 >= len(insertion) / 2.0 - ): + if overlap_length1 >= len(deletion) / 2.0 or overlap_length1 >= len(insertion) / 2.0: # Overlap found. Insert an equality and trim the surrounding edits. - diffs.insert( - pointer, (self.DIFF_EQUAL, insertion[:overlap_length1]) - ) + diffs.insert(pointer, (self.DIFF_EQUAL, insertion[:overlap_length1])) diffs[pointer - 1] = ( self.DIFF_DELETE, deletion[: len(deletion) - overlap_length1], @@ -747,15 +723,10 @@ class diff_match_patch: ) pointer += 1 else: - if ( - overlap_length2 >= len(deletion) / 2.0 - or overlap_length2 >= len(insertion) / 2.0 - ): + if overlap_length2 >= len(deletion) / 2.0 or overlap_length2 >= len(insertion) / 2.0: # Reverse overlap found. # Insert an equality and swap and trim the surrounding edits. - diffs.insert( - pointer, (self.DIFF_EQUAL, deletion[:overlap_length2]) - ) + diffs.insert(pointer, (self.DIFF_EQUAL, deletion[:overlap_length2])) diffs[pointer - 1] = ( self.DIFF_INSERT, insertion[: len(insertion) - overlap_length2], @@ -830,10 +801,7 @@ class diff_match_patch: pointer = 1 # Intentionally ignore the first and last element (don't need checking). while pointer < len(diffs) - 1: - if ( - diffs[pointer - 1][0] == self.DIFF_EQUAL - and diffs[pointer + 1][0] == self.DIFF_EQUAL - ): + if diffs[pointer - 1][0] == self.DIFF_EQUAL and diffs[pointer + 1][0] == self.DIFF_EQUAL: # This is a single edit surrounded by equalities. equality1 = diffs[pointer - 1][1] edit = diffs[pointer][1] @@ -851,16 +819,12 @@ class diff_match_patch: bestEquality1 = equality1 bestEdit = edit bestEquality2 = equality2 - bestScore = diff_cleanupSemanticScore( - equality1, edit - ) + diff_cleanupSemanticScore(edit, equality2) + bestScore = diff_cleanupSemanticScore(equality1, edit) + diff_cleanupSemanticScore(edit, equality2) while edit and equality2 and edit[0] == equality2[0]: equality1 += edit[0] edit = edit[1:] + equality2[0] equality2 = equality2[1:] - score = diff_cleanupSemanticScore( - equality1, edit - ) + diff_cleanupSemanticScore(edit, equality2) + score = diff_cleanupSemanticScore(equality1, edit) + diff_cleanupSemanticScore(edit, equality2) # The >= encourages trailing rather than leading whitespace on edits. if score >= bestScore: bestScore = score @@ -904,9 +868,7 @@ class diff_match_patch: post_del = False # Is there a deletion operation after the last equality. while pointer < len(diffs): if diffs[pointer][0] == self.DIFF_EQUAL: # Equality found. - if len(diffs[pointer][1]) < self.Diff_EditCost and ( - post_ins or post_del - ): + if len(diffs[pointer][1]) < self.Diff_EditCost and (post_ins or post_del): # Candidate found. equalities.append(pointer) pre_ins = post_ins @@ -933,10 +895,7 @@ class diff_match_patch: if lastequality and ( (pre_ins and pre_del and post_ins and post_del) - or ( - (len(lastequality) < self.Diff_EditCost / 2) - and (pre_ins + pre_del + post_ins + post_del) == 3 - ) + or ((len(lastequality) < self.Diff_EditCost / 2) and (pre_ins + pre_del + post_ins + post_del) == 3) ): # Duplicate record. diffs.insert(equalities[-1], (self.DIFF_DELETE, lastequality)) @@ -1001,9 +960,7 @@ class diff_match_patch: diffs[x][1] + text_insert[:commonlength], ) else: - diffs.insert( - 0, (self.DIFF_EQUAL, text_insert[:commonlength]) - ) + diffs.insert(0, (self.DIFF_EQUAL, text_insert[:commonlength])) pointer += 1 text_insert = text_insert[commonlength:] text_delete = text_delete[commonlength:] @@ -1018,13 +975,9 @@ class diff_match_patch: text_delete = text_delete[:-commonlength] # Delete the offending records and add the merged ones. if count_delete == 0: - diffs[pointer - count_insert : pointer] = [ - (self.DIFF_INSERT, text_insert) - ] + diffs[pointer - count_insert : pointer] = [(self.DIFF_INSERT, text_insert)] elif count_insert == 0: - diffs[pointer - count_delete : pointer] = [ - (self.DIFF_DELETE, text_delete) - ] + diffs[pointer - count_delete : pointer] = [(self.DIFF_DELETE, text_delete)] else: diffs[pointer - count_delete - count_insert : pointer] = [ (self.DIFF_DELETE, text_delete), @@ -1060,17 +1013,13 @@ class diff_match_patch: pointer = 1 # Intentionally ignore the first and last element (don't need checking). while pointer < len(diffs) - 1: - if ( - diffs[pointer - 1][0] == self.DIFF_EQUAL - and diffs[pointer + 1][0] == self.DIFF_EQUAL - ): + if diffs[pointer - 1][0] == self.DIFF_EQUAL and diffs[pointer + 1][0] == self.DIFF_EQUAL: # This is a single edit surrounded by equalities. if diffs[pointer][1].endswith(diffs[pointer - 1][1]): # Shift the edit over the previous equality. diffs[pointer] = ( diffs[pointer][0], - diffs[pointer - 1][1] - + diffs[pointer][1][: -len(diffs[pointer - 1][1])], + diffs[pointer - 1][1] + diffs[pointer][1][: -len(diffs[pointer - 1][1])], ) diffs[pointer + 1] = ( diffs[pointer + 1][0], @@ -1086,8 +1035,7 @@ class diff_match_patch: ) diffs[pointer] = ( diffs[pointer][0], - diffs[pointer][1][len(diffs[pointer + 1][1]) :] - + diffs[pointer + 1][1], + diffs[pointer][1][len(diffs[pointer + 1][1]) :] + diffs[pointer + 1][1], ) del diffs[pointer + 1] changes = True @@ -1140,12 +1088,7 @@ class diff_match_patch: """ html = [] for op, data in diffs: - text = ( - data.replace("&", "&") - .replace("<", "<") - .replace(">", ">") - .replace("\n", "¶
") - ) + text = data.replace("&", "&").replace("<", "<").replace(">", ">").replace("\n", "¶
") if op == self.DIFF_INSERT: html.append('%s' % text) elif op == self.DIFF_DELETE: @@ -1280,14 +1223,9 @@ class diff_match_patch: diffs.append((self.DIFF_DELETE, text)) else: # Anything else is an error. - raise ValueError( - "Invalid diff operation in diff_fromDelta: " + token[0] - ) + raise ValueError("Invalid diff operation in diff_fromDelta: " + token[0]) if pointer != len(text1): - raise ValueError( - "Delta length (%d) does not equal source text length (%d)." - % (pointer, len(text1)) - ) + raise ValueError("Delta length (%d) does not equal source text length (%d)." % (pointer, len(text1))) return diffs # MATCH FUNCTIONS @@ -1465,13 +1403,10 @@ class diff_match_patch: # Look for the first and last matches of pattern in text. If two different # matches are found, increase the pattern length. while text.find(pattern) != text.rfind(pattern) and ( - self.Match_MaxBits == 0 - or len(pattern) < self.Match_MaxBits - self.Patch_Margin - self.Patch_Margin + self.Match_MaxBits == 0 or len(pattern) < self.Match_MaxBits - self.Patch_Margin - self.Patch_Margin ): padding += self.Patch_Margin - pattern = text[ - max(0, patch.start2 - padding) : patch.start2 + patch.length1 + padding - ] + pattern = text[max(0, patch.start2 - padding) : patch.start2 + patch.length1 + padding] # Add one chunk for good luck. padding += self.Patch_Margin @@ -1480,9 +1415,7 @@ class diff_match_patch: if prefix: patch.diffs[:0] = [(self.DIFF_EQUAL, prefix)] # Add the suffix. - suffix = text[ - patch.start2 + patch.length1 : patch.start2 + patch.length1 + padding - ] + suffix = text[patch.start2 + patch.length1 : patch.start2 + patch.length1 + padding] if suffix: patch.diffs.append((self.DIFF_EQUAL, suffix)) @@ -1564,19 +1497,12 @@ class diff_match_patch: # Insertion patch.diffs.append(diffs[x]) patch.length2 += len(diff_text) - postpatch_text = ( - postpatch_text[:char_count2] - + diff_text - + postpatch_text[char_count2:] - ) + postpatch_text = postpatch_text[:char_count2] + diff_text + postpatch_text[char_count2:] elif diff_type == self.DIFF_DELETE: # Deletion. patch.length1 += len(diff_text) patch.diffs.append(diffs[x]) - postpatch_text = ( - postpatch_text[:char_count2] - + postpatch_text[char_count2 + len(diff_text) :] - ) + postpatch_text = postpatch_text[:char_count2] + postpatch_text[char_count2 + len(diff_text) :] elif ( diff_type == self.DIFF_EQUAL and len(diff_text) <= 2 * self.Patch_Margin @@ -1668,9 +1594,7 @@ class diff_match_patch: if len(text1) > self.Match_MaxBits: # patch_splitMax will only provide an oversized pattern in the case of # a monster delete. - start_loc = self.match_main( - text, text1[: self.Match_MaxBits], expected_loc - ) + start_loc = self.match_main(text, text1[: self.Match_MaxBits], expected_loc) if start_loc != -1: end_loc = self.match_main( text, @@ -1697,19 +1621,14 @@ class diff_match_patch: text2 = text[start_loc : end_loc + self.Match_MaxBits] if text1 == text2: # Perfect match, just shove the replacement text in. - text = ( - text[:start_loc] - + self.diff_text2(patch.diffs) - + text[start_loc + len(text1) :] - ) + text = text[:start_loc] + self.diff_text2(patch.diffs) + text[start_loc + len(text1) :] else: # Imperfect match. # Run a diff to get a framework of equivalent indices. diffs = self.diff_main(text1, text2, False) if ( len(text1) > self.Match_MaxBits - and self.diff_levenshtein(diffs) / float(len(text1)) - > self.Patch_DeleteThreshold + and self.diff_levenshtein(diffs) / float(len(text1)) > self.Patch_DeleteThreshold ): # The end points match, but the content is unacceptably bad. results[-1] = False @@ -1720,18 +1639,11 @@ class diff_match_patch: if op != self.DIFF_EQUAL: index2 = self.diff_xIndex(diffs, index1) if op == self.DIFF_INSERT: # Insertion - text = ( - text[: start_loc + index2] - + data - + text[start_loc + index2 :] - ) + text = text[: start_loc + index2] + data + text[start_loc + index2 :] elif op == self.DIFF_DELETE: # Deletion text = ( text[: start_loc + index2] - + text[ - start_loc - + self.diff_xIndex(diffs, index1 + len(data)) : - ] + + text[start_loc + self.diff_xIndex(diffs, index1 + len(data)) :] ) if op != self.DIFF_DELETE: index1 += len(data) @@ -1830,10 +1742,7 @@ class diff_match_patch: patch.length1 = patch.length2 = len(precontext) patch.diffs.append((self.DIFF_EQUAL, precontext)) - while ( - len(bigpatch.diffs) != 0 - and patch.length1 < patch_size - self.Patch_Margin - ): + while len(bigpatch.diffs) != 0 and patch.length1 < patch_size - self.Patch_Margin: (diff_type, diff_text) = bigpatch.diffs[0] if diff_type == self.DIFF_INSERT: # Insertions are harmless. @@ -1855,9 +1764,7 @@ class diff_match_patch: del bigpatch.diffs[0] else: # Deletion or equality. Only take as much as we can stomach. - diff_text = diff_text[ - : patch_size - patch.length1 - self.Patch_Margin - ] + diff_text = diff_text[: patch_size - patch.length1 - self.Patch_Margin] patch.length1 += len(diff_text) start1 += len(diff_text) if diff_type == self.DIFF_EQUAL: diff --git a/rhodecode/lib/diffs.py b/rhodecode/lib/diffs.py index ff310961..6a756811 100644 --- a/rhodecode/lib/diffs.py +++ b/rhodecode/lib/diffs.py @@ -20,6 +20,7 @@ """ Set of diffing helpers, previously part of vcs """ + import dataclasses import os import re @@ -46,18 +47,18 @@ DEFAULT_CONTEXT = 3 def get_diff_context(request): - return MAX_CONTEXT if request.GET.get('fullcontext', '') == '1' else DEFAULT_CONTEXT + return MAX_CONTEXT if request.GET.get("fullcontext", "") == "1" else DEFAULT_CONTEXT def get_diff_whitespace_flag(request): - return request.GET.get('ignorews', '') == '1' + return request.GET.get("ignorews", "") == "1" @dataclasses.dataclass class OPS: - ADD: str = 'A' - MOD: str = 'M' - DEL: str = 'D' + ADD: str = "A" + MOD: str = "M" + DEL: str = "D" @dataclasses.dataclass @@ -84,7 +85,7 @@ def get_gitdiff(filenode_old, filenode_new, ignore_whitespace=True, context=3): submodules = [o for o in [filenode_new, filenode_old] if isinstance(o, SubModuleNode)] if submodules: - return '' + return "" for filenode in (filenode_old, filenode_new): if not isinstance(filenode, FileNode): @@ -95,10 +96,11 @@ def get_gitdiff(filenode_old, filenode_new, ignore_whitespace=True, context=3): new_commit = filenode_new.commit vcs_gitdiff = repo.get_diff( - old_commit, new_commit, filenode_new.path, - ignore_whitespace, context, path1=filenode_old.path) + old_commit, new_commit, filenode_new.path, ignore_whitespace, context, path1=filenode_old.path + ) return vcs_gitdiff + NEW_FILENODE = 1 DEL_FILENODE = 2 MOD_FILENODE = 3 @@ -109,7 +111,6 @@ BIN_FILENODE = 7 class LimitedDiffContainer(object): - def __init__(self, diff_limit: int, cur_diff_size, diff): self.diff = diff self.diff_limit = diff_limit @@ -127,13 +128,13 @@ class Action(object): Contains constants for the action value of the lines in a parsed diff. """ - ADD = 'add' - DELETE = 'del' - UNMODIFIED = 'unmod' + ADD = "add" + DELETE = "del" + UNMODIFIED = "unmod" - CONTEXT = 'context' - OLD_NO_NL = 'old-no-nl' - NEW_NO_NL = 'new-no-nl' + CONTEXT = "context" + OLD_NO_NL = "old-no-nl" + NEW_NO_NL = "new-no-nl" class DiffProcessor(object): @@ -149,17 +150,19 @@ class DiffProcessor(object): since the result is intended for presentation to the user. """ - _chunk_re = re.compile(br'^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)') - _newline_marker = re.compile(br'^\\ No newline at end of file') + + _chunk_re = re.compile(rb"^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@(.*)") + _newline_marker = re.compile(rb"^\\ No newline at end of file") # used for inline highlighter word split - _token_re = re.compile(br'()(>|<|&|\W+?)') + _token_re = re.compile(rb"()(>|<|&|\W+?)") # collapse ranges of commits over given number _collapse_commits_over = 5 - def __init__(self, diff: base.Diff, diff_format='gitdiff', diff_limit: int = 0, - file_limit: int = 0, show_full_diff=True): + def __init__( + self, diff: base.Diff, diff_format="gitdiff", diff_limit: int = 0, file_limit: int = 0, show_full_diff=True + ): """ :param diff: A `Diff` object representing a diff from a vcs backend :param diff_format: format of diff passed, `udiff` or `gitdiff` @@ -179,14 +182,14 @@ class DiffProcessor(object): self.parsed = False self.parsed_diff = [] - log.debug('Initialized DiffProcessor with %s mode', diff_format) + log.debug("Initialized DiffProcessor with %s mode", diff_format) self.differ = self._highlight_line_udiff self._parser = self._new_parse_gitdiff - if diff_format == 'gitdiff': + if diff_format == "gitdiff": self.differ = self._highlight_line_difflib self._parser = self._parse_gitdiff - raise DeprecationWarning('gitdiff usage is deprecated') + raise DeprecationWarning("gitdiff usage is deprecated") def _copy_iterator(self): """ @@ -206,12 +209,9 @@ class DiffProcessor(object): self.cur_diff_size += len(diff_string) if not self.show_full_diff and (self.cur_diff_size > self.diff_limit): - raise DiffLimitExceeded('Diff Limit Exceeded') + raise DiffLimitExceeded("Diff Limit Exceeded") - return diff_string \ - .replace(b'&', b'&')\ - .replace(b'<', b'<')\ - .replace(b'>', b'>') + return diff_string.replace(b"&", b"&").replace(b"<", b"<").replace(b">", b">") def _line_counter(self, diff_line): """ @@ -219,9 +219,9 @@ class DiffProcessor(object): :param diff_line: """ - if diff_line.startswith(b'+') and not diff_line.startswith(b'+++'): + if diff_line.startswith(b"+") and not diff_line.startswith(b"+++"): self.adds += 1 - elif diff_line.startswith(b'-') and not diff_line.startswith(b'---'): + elif diff_line.startswith(b"-") and not diff_line.startswith(b"---"): self.removes += 1 return diff_line @@ -230,56 +230,58 @@ class DiffProcessor(object): Highlight inline changes in both lines. """ - if line['action'] == Action.DELETE: + if line["action"] == Action.DELETE: old, new = line, next_ else: old, new = next_, line - oldwords = self._token_re.split(old['line']) - newwords = self._token_re.split(new['line']) + oldwords = self._token_re.split(old["line"]) + newwords = self._token_re.split(new["line"]) sequence = difflib.SequenceMatcher(None, oldwords, newwords) oldfragments, newfragments = [], [] for tag, i1, i2, j1, j2 in sequence.get_opcodes(): - oldfrag = ''.join(oldwords[i1:i2]) - newfrag = ''.join(newwords[j1:j2]) - if tag != 'equal': + oldfrag = "".join(oldwords[i1:i2]) + newfrag = "".join(newwords[j1:j2]) + if tag != "equal": if oldfrag: - oldfrag = f'{oldfrag}' + oldfrag = f"{oldfrag}" if newfrag: - newfrag = f'{newfrag}' + newfrag = f"{newfrag}" oldfragments.append(oldfrag) newfragments.append(newfrag) - old['line'] = "".join(oldfragments) - new['line'] = "".join(newfragments) + old["line"] = "".join(oldfragments) + new["line"] = "".join(newfragments) def _highlight_line_udiff(self, line, next_): """ Highlight inline changes in both lines. """ start = 0 - limit = min(len(line['line']), len(next_['line'])) - while start < limit and line['line'][start] == next_['line'][start]: + limit = min(len(line["line"]), len(next_["line"])) + while start < limit and line["line"][start] == next_["line"][start]: start += 1 end = -1 limit -= start - while -end <= limit and line['line'][end] == next_['line'][end]: + while -end <= limit and line["line"][end] == next_["line"][end]: end -= 1 end += 1 if start or end: + def do(l): - last = end + len(l['line']) - if l['action'] == Action.ADD: - tag = 'ins' + last = end + len(l["line"]) + if l["action"] == Action.ADD: + tag = "ins" else: - tag = 'del' - l['line'] = f"{l['line'][:start]}<{tag}>{l['line'][start:last]}{l['line'][last:]}" + tag = "del" + l["line"] = f"{l['line'][:start]}<{tag}>{l['line'][start:last]}{l['line'][last:]}" + do(line) do(next_) def _clean_line(self, line, command: str): - if command in ['+', '-', ' ']: + if command in ["+", "-", " "]: # only modify the line if it's actually a diff thing line = line[1:] return line @@ -300,68 +302,73 @@ class DiffProcessor(object): op = None stats = { - 'added': 0, - 'deleted': 0, - 'binary': False, - 'ops': {}, + "added": 0, + "deleted": 0, + "binary": False, + "ops": {}, } - if head['deleted_file_mode']: + if head["deleted_file_mode"]: op = OPS.DEL - stats['binary'] = True - stats['ops'][DEL_FILENODE] = 'deleted file' + stats["binary"] = True + stats["ops"][DEL_FILENODE] = "deleted file" - elif head['new_file_mode']: + elif head["new_file_mode"]: op = OPS.ADD - stats['binary'] = True - stats['ops'][NEW_FILENODE] = f"new file {safe_str(head['new_file_mode'])}" + stats["binary"] = True + stats["ops"][NEW_FILENODE] = f"new file {safe_str(head['new_file_mode'])}" else: # modify operation, can be: copy, rename or chmod - # CHMOD - if head['new_mode'] and head['old_mode']: + if head["new_mode"] and head["old_mode"]: op = OPS.MOD - stats['binary'] = True - stats['ops'][CHMOD_FILENODE] = f"modified file chmod {safe_str(head['old_mode'])} => {safe_str(head['new_mode'])}" + stats["binary"] = True + stats["ops"][CHMOD_FILENODE] = ( + f"modified file chmod {safe_str(head['old_mode'])} => {safe_str(head['new_mode'])}" + ) # RENAME - if head['rename_from'] != head['rename_to']: + if head["rename_from"] != head["rename_to"]: op = OPS.MOD - stats['binary'] = True - stats['ops'][RENAMED_FILENODE] = f"file renamed from {safe_str(head['rename_from'])} to {safe_str(head['rename_to'])}" + stats["binary"] = True + stats["ops"][RENAMED_FILENODE] = ( + f"file renamed from {safe_str(head['rename_from'])} to {safe_str(head['rename_to'])}" + ) # COPY - if head.get('copy_from') and head.get('copy_to'): + if head.get("copy_from") and head.get("copy_to"): op = OPS.MOD - stats['binary'] = True - stats['ops'][COPIED_FILENODE] = f"file copied from {safe_str(head['copy_from'])} to {safe_str(head['copy_to'])}" + stats["binary"] = True + stats["ops"][COPIED_FILENODE] = ( + f"file copied from {safe_str(head['copy_from'])} to {safe_str(head['copy_to'])}" + ) # If our new parsed headers didn't match anything fallback to # old style detection if op is None: - if not head['a_file'] and head['b_file']: + if not head["a_file"] and head["b_file"]: op = OPS.ADD - stats['binary'] = True - stats['ops'][NEW_FILENODE] = 'new file' + stats["binary"] = True + stats["ops"][NEW_FILENODE] = "new file" - elif head['a_file'] and not head['b_file']: + elif head["a_file"] and not head["b_file"]: op = OPS.DEL - stats['binary'] = True - stats['ops'][DEL_FILENODE] = 'deleted file' + stats["binary"] = True + stats["ops"][DEL_FILENODE] = "deleted file" # it's not ADD not DELETE if op is None: op = OPS.MOD - stats['binary'] = True - stats['ops'][MOD_FILENODE] = 'modified file' + stats["binary"] = True + stats["ops"][MOD_FILENODE] = "modified file" # a real non-binary diff - if head['a_file'] or head['b_file']: + if head["a_file"] or head["b_file"]: try: raw_diff, chunks, _stats = self._parse_lines(diff) - stats['binary'] = False - stats['added'] = _stats[0] - stats['deleted'] = _stats[1] + stats["binary"] = False + stats["added"] = _stats[0] + stats["deleted"] = _stats[1] # explicit mark that it's a modified file if op == OPS.MOD: - stats['ops'][MOD_FILENODE] = 'modified file' + stats["ops"][MOD_FILENODE] = "modified file" exceeds_limit = len(raw_diff) > self.file_limit # changed from _escaper function so we validate size of @@ -370,9 +377,10 @@ class DiffProcessor(object): # from my tests, big files are fairly safe to be parsed # but the browser is the bottleneck if not self.show_full_diff and exceeds_limit: - raise DiffLimitExceeded('File Limit Exceeded') + raise DiffLimitExceeded("File Limit Exceeded") except DiffLimitExceeded: + def diff_container(_diff): return LimitedDiffContainer(self.diff_limit, self.cur_diff_size, _diff) @@ -381,10 +389,10 @@ class DiffProcessor(object): chunks = [] else: # GIT format binary patch, or possibly empty diff - if head['bin_patch']: + if head["bin_patch"]: # we have operation already extracted, but we mark simply # it's a diff we won't show for binary files - stats['ops'][BIN_FILENODE] = 'binary diff hidden' + stats["ops"][BIN_FILENODE] = "binary diff hidden" chunks = [] if chunks and not self.show_full_diff and op == OPS.DEL: @@ -393,46 +401,49 @@ class DiffProcessor(object): # to see the content of the file chunks = [] - frag = [{ - 'old_lineno': '', - 'new_lineno': '', - 'action': Action.CONTEXT, - 'line': msg, - } for _op, msg in list(stats['ops'].items()) - if _op not in [MOD_FILENODE]] + frag = [ + { + "old_lineno": "", + "new_lineno": "", + "action": Action.CONTEXT, + "line": msg, + } + for _op, msg in list(stats["ops"].items()) + if _op not in [MOD_FILENODE] + ] chunks.insert(0, frag) - _files.append({ - 'filename': safe_str(head['b_path']), - 'old_revision': head['a_blob_id'], - 'new_revision': head['b_blob_id'], - 'chunks': chunks, - 'raw_diff': safe_str(raw_diff), - 'operation': op, - 'stats': stats, - 'exceeds_limit': exceeds_limit, - 'is_limited_diff': limited_diff, - }) + _files.append( + { + "filename": safe_str(head["b_path"]), + "old_revision": head["a_blob_id"], + "new_revision": head["b_blob_id"], + "chunks": chunks, + "raw_diff": safe_str(raw_diff), + "operation": op, + "stats": stats, + "exceeds_limit": exceeds_limit, + "is_limited_diff": limited_diff, + } + ) def operation_sorter(info): - return {OPS.ADD: 0, OPS.MOD: 1, OPS.DEL: 2}.get(info['operation']) + return {OPS.ADD: 0, OPS.MOD: 1, OPS.DEL: 2}.get(info["operation"]) if not inline_diff: return diff_container(sorted(_files, key=operation_sorter)) # highlight inline changes for diff_data in _files: - for chunk in diff_data['chunks']: + for chunk in diff_data["chunks"]: lineiter = iter(chunk) try: while 1: line = next(lineiter) - if line['action'] not in ( - Action.UNMODIFIED, Action.CONTEXT): + if line["action"] not in (Action.UNMODIFIED, Action.CONTEXT): nextline = next(lineiter) - if nextline['action'] in ['unmod', 'context'] or \ - nextline['action'] == line['action']: + if nextline["action"] in ["unmod", "context"] or nextline["action"] == line["action"]: continue self.differ(line, nextline) except StopIteration: @@ -442,9 +453,9 @@ class DiffProcessor(object): def _check_large_diff(self): if self.diff_limit: - log.debug('Checking if diff exceeds current diff_limit of %s', self.diff_limit) + log.debug("Checking if diff exceeds current diff_limit of %s", self.diff_limit) if not self.show_full_diff and (self.cur_diff_size > self.diff_limit): - raise DiffLimitExceeded(f'Diff Limit `{self.diff_limit}` Exceeded') + raise DiffLimitExceeded(f"Diff Limit `{self.diff_limit}` Exceeded") # FIXME: NEWDIFFS: dan: this replaces _parse_gitdiff def _new_parse_gitdiff(self, inline_diff=True): @@ -458,7 +469,7 @@ class DiffProcessor(object): bytes_head = chunk.header head = chunk.header_as_str - log.debug('parsing diff chunk %r', chunk) + log.debug("parsing diff chunk %r", chunk) raw_diff = chunk.raw limited_diff = False @@ -466,77 +477,77 @@ class DiffProcessor(object): op = None stats = { - 'added': 0, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {}, + "added": 0, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {}, } - if head['old_mode']: - stats['old_mode'] = head['old_mode'] - if head['new_mode']: - stats['new_mode'] = head['new_mode'] - if head['b_mode']: - stats['new_mode'] = head['b_mode'] + if head["old_mode"]: + stats["old_mode"] = head["old_mode"] + if head["new_mode"]: + stats["new_mode"] = head["new_mode"] + if head["b_mode"]: + stats["new_mode"] = head["b_mode"] # delete file - if head['deleted_file_mode']: + if head["deleted_file_mode"]: op = OPS.DEL - stats['binary'] = True - stats['ops'][DEL_FILENODE] = 'deleted file' + stats["binary"] = True + stats["ops"][DEL_FILENODE] = "deleted file" # new file - elif head['new_file_mode']: + elif head["new_file_mode"]: op = OPS.ADD - stats['binary'] = True - stats['old_mode'] = '' - stats['new_mode'] = head['new_file_mode'] - stats['ops'][NEW_FILENODE] = f"new file {head['new_file_mode']}" + stats["binary"] = True + stats["old_mode"] = "" + stats["new_mode"] = head["new_file_mode"] + stats["ops"][NEW_FILENODE] = f"new file {head['new_file_mode']}" # modify operation, can be: copy, rename or chmod else: # CHMOD - if head['new_mode'] and head['old_mode']: + if head["new_mode"] and head["old_mode"]: op = OPS.MOD - stats['binary'] = True - stats['ops'][CHMOD_FILENODE] = f"modified file chmod {head['old_mode']} => {head['new_mode']}" + stats["binary"] = True + stats["ops"][CHMOD_FILENODE] = f"modified file chmod {head['old_mode']} => {head['new_mode']}" # RENAME - if head['rename_from'] != head['rename_to']: + if head["rename_from"] != head["rename_to"]: op = OPS.MOD - stats['binary'] = True - stats['renamed'] = (head['rename_from'], head['rename_to']) - stats['ops'][RENAMED_FILENODE] = f"file renamed from {head['rename_from']} to {head['rename_to']}" + stats["binary"] = True + stats["renamed"] = (head["rename_from"], head["rename_to"]) + stats["ops"][RENAMED_FILENODE] = f"file renamed from {head['rename_from']} to {head['rename_to']}" # COPY - if head.get('copy_from') and head.get('copy_to'): + if head.get("copy_from") and head.get("copy_to"): op = OPS.MOD - stats['binary'] = True - stats['copied'] = (head['copy_from'], head['copy_to']) - stats['ops'][COPIED_FILENODE] = f"file copied from {head['copy_from']} to {head['copy_to']}" + stats["binary"] = True + stats["copied"] = (head["copy_from"], head["copy_to"]) + stats["ops"][COPIED_FILENODE] = f"file copied from {head['copy_from']} to {head['copy_to']}" # If our new parsed headers didn't match anything fallback to # old style detection if op is None: - if not head['a_file'] and head['b_file']: + if not head["a_file"] and head["b_file"]: op = OPS.ADD - stats['binary'] = True - stats['new_file'] = True - stats['ops'][NEW_FILENODE] = 'new file' + stats["binary"] = True + stats["new_file"] = True + stats["ops"][NEW_FILENODE] = "new file" - elif head['a_file'] and not head['b_file']: + elif head["a_file"] and not head["b_file"]: op = OPS.DEL - stats['binary'] = True - stats['ops'][DEL_FILENODE] = 'deleted file' + stats["binary"] = True + stats["ops"][DEL_FILENODE] = "deleted file" # it's not ADD not DELETE if op is None: op = OPS.MOD - stats['binary'] = True - stats['ops'][MOD_FILENODE] = 'modified file' + stats["binary"] = True + stats["ops"][MOD_FILENODE] = "modified file" # a real non-binary diff - if head['a_file'] or head['b_file']: + if head["a_file"] or head["b_file"]: # simulate splitlines, so we keep the line end part diff = self.diff_splitter(chunk.diff) @@ -552,21 +563,21 @@ class DiffProcessor(object): # From the tests big files are fairly safe to be parsed # but the browser is the bottleneck. if not self.show_full_diff and exceeds_limit: - log.debug('File `%s` exceeds current file_limit of %s', - head['b_path'], self.file_limit) - raise DiffLimitExceeded(f'File Limit {self.file_limit} Exceeded') + log.debug("File `%s` exceeds current file_limit of %s", head["b_path"], self.file_limit) + raise DiffLimitExceeded(f"File Limit {self.file_limit} Exceeded") self._check_large_diff() raw_diff, chunks, _stats = self._new_parse_lines(diff) - stats['binary'] = False - stats['added'] = _stats[0] - stats['deleted'] = _stats[1] + stats["binary"] = False + stats["added"] = _stats[0] + stats["deleted"] = _stats[1] # explicit mark that it's a modified file if op == OPS.MOD: - stats['ops'][MOD_FILENODE] = 'modified file' + stats["ops"][MOD_FILENODE] = "modified file" except DiffLimitExceeded: + def limited_diff_container(_diff): return LimitedDiffContainer(self.diff_limit, self.cur_diff_size, _diff) @@ -577,10 +588,10 @@ class DiffProcessor(object): chunks = [] else: # GIT format binary patch, or possibly empty diff - if head['bin_patch']: + if head["bin_patch"]: # we have operation already extracted, but we mark simply # it's a diff we won't show for binary files - stats['ops'][BIN_FILENODE] = 'binary diff hidden' + stats["ops"][BIN_FILENODE] = "binary diff hidden" chunks = [] # Hide content of deleted node by setting empty chunks @@ -591,38 +602,44 @@ class DiffProcessor(object): chunks = [] frag = [ - {'old_lineno': '', - 'new_lineno': '', - 'action': Action.CONTEXT, - 'line': msg, - } for _op, msg in list(stats['ops'].items()) - if _op not in [MOD_FILENODE]] + { + "old_lineno": "", + "new_lineno": "", + "action": Action.CONTEXT, + "line": msg, + } + for _op, msg in list(stats["ops"].items()) + if _op not in [MOD_FILENODE] + ] chunks.insert(0, frag) - original_filename = head['a_path'] - original_filename_bytes = bytes_head['a_path'] + original_filename = head["a_path"] + original_filename_bytes = bytes_head["a_path"] - filename = head['b_path'] - filename_bytes = bytes_head['b_path'] + filename = head["b_path"] + filename_bytes = bytes_head["b_path"] - _files.append({ - 'original_filename': original_filename, - 'original_filename_bytes': original_filename_bytes, - 'filename': filename, - 'filename_bytes': filename_bytes, - 'old_revision': head['a_blob_id'], - 'new_revision': head['b_blob_id'], - 'chunks': chunks, - 'raw_diff': safe_str(raw_diff), - 'operation': op, - 'stats': stats, - 'exceeds_limit': exceeds_limit, - 'is_limited_diff': limited_diff, - }) + _files.append( + { + "original_filename": original_filename, + "original_filename_bytes": original_filename_bytes, + "filename": filename, + "filename_bytes": filename_bytes, + "old_revision": head["a_blob_id"], + "new_revision": head["b_blob_id"], + "chunks": chunks, + "raw_diff": safe_str(raw_diff), + "operation": op, + "stats": stats, + "exceeds_limit": exceeds_limit, + "is_limited_diff": limited_diff, + } + ) def sorter(info): - return {OPS.ADD: 0, OPS.MOD: 1, OPS.DEL: 2}.get(info['operation']) + return {OPS.ADD: 0, OPS.MOD: 1, OPS.DEL: 2}.get(info["operation"]) + return diff_container(sorted(_files, key=sorter)) # FIXME: NEWDIFFS: dan: this gets replaced by _new_parse_lines @@ -649,8 +666,7 @@ class DiffProcessor(object): break gr = match.groups() - (old_line, old_end, - new_line, new_end) = [int(x or 1) for x in gr[:-1]] + (old_line, old_end, new_line, new_end) = [int(x or 1) for x in gr[:-1]] old_line -= 1 new_line -= 1 @@ -661,30 +677,32 @@ class DiffProcessor(object): if context: # skip context only if it's first line if int(gr[0]) > 1: - lines.append({ - 'old_lineno': '...', - 'new_lineno': '...', - 'action': Action.CONTEXT, - 'line': line, - }) + lines.append( + { + "old_lineno": "...", + "new_lineno": "...", + "action": Action.CONTEXT, + "line": line, + } + ) line = next(diff_iter) while old_line < old_end or new_line < new_end: - command = b' ' + command = b" " if line: command = line[0] affects_old = affects_new = False # ignore those if we don't expect them - if command in b'#@': + if command in b"#@": continue - elif command == b'+': + elif command == b"+": affects_new = True action = Action.ADD stats[0] += 1 - elif command == b'-': + elif command == b"-": affects_old = True action = Action.DELETE stats[1] += 1 @@ -695,12 +713,14 @@ class DiffProcessor(object): if not self._newline_marker.match(line): old_line += affects_old new_line += affects_new - lines.append({ - 'old_lineno': affects_old and old_line or b'', - 'new_lineno': affects_new and new_line or b'', - 'action': action, - 'line': self._clean_line(line, command) - }) + lines.append( + { + "old_lineno": affects_old and old_line or b"", + "new_lineno": affects_new and new_line or b"", + "action": action, + "line": self._clean_line(line, command), + } + ) raw_diff.append(line) line = next(diff_iter) @@ -708,16 +728,18 @@ class DiffProcessor(object): if self._newline_marker.match(line): # we need to append to lines, since this is not # counted in the line specs of diff - lines.append({ - 'old_lineno': '...', - 'new_lineno': '...', - 'action': Action.CONTEXT, - 'line': self._clean_line(line, command) - }) + lines.append( + { + "old_lineno": "...", + "new_lineno": "...", + "action": Action.CONTEXT, + "line": self._clean_line(line, command), + } + ) except StopIteration: pass - return ''.join(raw_diff), chunks, stats + return "".join(raw_diff), chunks, stats # FIXME: NEWDIFFS: dan: this replaces _parse_lines def _new_parse_lines(self, diff_iter): @@ -743,17 +765,16 @@ class DiffProcessor(object): gr = match.groups() - (old_line, old_end, - new_line, new_end) = [int(x or 1) for x in gr[:-1]] + (old_line, old_end, new_line, new_end) = [int(x or 1) for x in gr[:-1]] lines = [] hunk = { - 'section_header': gr[-1], - 'source_start': old_line, - 'source_length': old_end, - 'target_start': new_line, - 'target_length': new_end, - 'lines': lines, + "section_header": gr[-1], + "source_start": old_line, + "source_length": old_end, + "target_start": new_line, + "target_length": new_end, + "lines": lines, } chunks.append(hunk) @@ -767,7 +788,7 @@ class DiffProcessor(object): line = next(diff_iter) while old_line < old_end or new_line < new_end: - command = ' ' + command = " " if line: # This is bytes, so we need to convert it to a str command: str = chr(line[0]) @@ -775,13 +796,13 @@ class DiffProcessor(object): affects_old = affects_new = False # ignore those if we don't expect them - if command in '#@': + if command in "#@": continue - elif command == '+': + elif command == "+": affects_new = True action = Action.ADD stats[0] += 1 - elif command == '-': + elif command == "-": affects_old = True action = Action.DELETE stats[1] += 1 @@ -792,12 +813,14 @@ class DiffProcessor(object): if not self._newline_marker.match(line): old_line += affects_old new_line += affects_new - lines.append({ - 'old_lineno': affects_old and old_line or None, - 'new_lineno': affects_new and new_line or None, - 'action': action, - 'line': self._clean_line(line, command) - }) + lines.append( + { + "old_lineno": affects_old and old_line or None, + "new_lineno": affects_new and new_line or None, + "action": action, + "line": self._clean_line(line, command), + } + ) raw_diff.append(line) line = next(diff_iter) @@ -810,19 +833,21 @@ class DiffProcessor(object): elif affects_new: action = Action.NEW_NO_NL else: - raise Exception('invalid context for no newline') + raise Exception("invalid context for no newline") - lines.append({ - 'old_lineno': None, - 'new_lineno': None, - 'action': action, - 'line': self._clean_line(line, command) - }) + lines.append( + { + "old_lineno": None, + "new_lineno": None, + "action": action, + "line": self._clean_line(line, command), + } + ) except StopIteration: pass - return b''.join(raw_diff), chunks, stats + return b"".join(raw_diff), chunks, stats def _safe_id(self, idstring): r"""Make a string safe for including in an id attribute. @@ -840,9 +865,9 @@ class DiffProcessor(object): """ # Transform all whitespace to underscore - idstring = re.sub(r'\s', "_", f'{idstring}') + idstring = re.sub(r"\s", "_", f"{idstring}") # Remove everything that is not a hyphen or a member of \w - idstring = re.sub(r'(?!-)\W', "", idstring).lower() + idstring = re.sub(r"(?!-)\W", "", idstring).lower() return idstring @classmethod @@ -852,12 +877,11 @@ class DiffProcessor(object): """ if not diff_string: return - elif diff_string == b'\n': - yield b'\n' + elif diff_string == b"\n": + yield b"\n" else: - - has_newline = diff_string.endswith(b'\n') - elements = diff_string.split(b'\n') + has_newline = diff_string.endswith(b"\n") + elements = diff_string.split(b"\n") if has_newline: # skip last element as it's empty string from newlines elements = elements[:-1] @@ -869,7 +893,7 @@ class DiffProcessor(object): if last_line and not has_newline: yield line else: - yield line + b'\n' + yield line + b"\n" def prepare(self, inline_diff=True): """ @@ -895,7 +919,8 @@ class DiffProcessor(object): return self.adds, self.removes def get_context_of_line( - self, path, diff_line: DiffLineNumber = None, context_before: int = 3, context_after: int = 3): + self, path, diff_line: DiffLineNumber = None, context_before: int = 3, context_after: int = 3 + ): """ Returns the context lines for the specified diff line. """ @@ -909,18 +934,14 @@ class DiffProcessor(object): first_line_to_include = max(idx - context_before, 0) first_line_after_context = idx + context_after + 1 - context_lines = chunk['lines'][first_line_to_include:first_line_after_context] + context_lines = chunk["lines"][first_line_to_include:first_line_after_context] - line_contents = [ - _context_line(line) for line in context_lines - if _is_diff_content(line) - ] + line_contents = [_context_line(line) for line in context_lines if _is_diff_content(line)] # TODO: johbo: Interim fixup, the diff chunks drop the final newline. # Once they are fixed, we can drop this line here. if line_contents: - line_contents[-1] = ( - line_contents[-1][0], line_contents[-1][1].rstrip(b'\n') + b'\n') + line_contents[-1] = (line_contents[-1][0], line_contents[-1][1].rstrip(b"\n") + b"\n") return line_contents def find_context(self, path, context, offset=0): @@ -935,18 +956,16 @@ class DiffProcessor(object): within the given `context`. """ if offset < 0 or offset >= len(context): - raise ValueError( - "Only positive values up to the length of the context " - "minus one are allowed.") + raise ValueError("Only positive values up to the length of the context minus one are allowed.") matches = [] file_diff = self._get_file_diff(path) - for chunk in file_diff['chunks']: + for chunk in file_diff["chunks"]: if not isinstance(chunk, dict): continue context_iter = iter(context) - for line_idx, line in enumerate(chunk['lines']): + for line_idx, line in enumerate(chunk["lines"]): try: if _context_line(line) == next(context_iter): continue @@ -964,43 +983,42 @@ class DiffProcessor(object): effective_offset = len(context) - offset found_at_diff_lines = [ - _line_to_diff_line_number(chunk['lines'][idx - effective_offset]) - for idx, chunk in matches] + _line_to_diff_line_number(chunk["lines"][idx - effective_offset]) for idx, chunk in matches + ] return found_at_diff_lines def _get_file_diff(self, path): for file_diff in self.parsed_diff: - if file_diff['filename'] == path: + if file_diff["filename"] == path: break else: raise FileNotInDiffException(f"File {path} not in diff") return file_diff def _find_chunk_line_index(self, file_diff, diff_line): - for chunk in file_diff['chunks']: + for chunk in file_diff["chunks"]: if not isinstance(chunk, dict): continue - for line_idx, line in enumerate(chunk['lines']): - if diff_line.old and line['old_lineno'] == diff_line.old: + for line_idx, line in enumerate(chunk["lines"]): + if diff_line.old and line["old_lineno"] == diff_line.old: return chunk, line_idx - if diff_line.new and line['new_lineno'] == diff_line.new: + if diff_line.new and line["new_lineno"] == diff_line.new: return chunk, line_idx raise LineNotInDiffException(f"The line {diff_line} is not part of the diff.") def _is_diff_content(line): - return line['action'] in ( - Action.UNMODIFIED, Action.ADD, Action.DELETE) + return line["action"] in (Action.UNMODIFIED, Action.ADD, Action.DELETE) def _context_line(line): - return line['action'], line['line'] + return line["action"], line["line"] def _line_to_diff_line_number(line): - new_line_no = line['new_lineno'] or None - old_line_no = line['old_lineno'] or None + new_line_no = line["new_lineno"] or None + old_line_no = line["old_lineno"] or None return DiffLineNumber(old=old_line_no, new=new_line_no) @@ -1028,7 +1046,7 @@ class DiffLimitExceeded(Exception): # NOTE(marcink): if diffs.mako change, probably this # needs a bump to next version -CURRENT_DIFF_VERSION = 'v5' +CURRENT_DIFF_VERSION = "v5" def _cleanup_cache_file(cached_diff_file): @@ -1036,74 +1054,66 @@ def _cleanup_cache_file(cached_diff_file): try: os.remove(cached_diff_file) except Exception: - log.exception('Failed to cleanup path %s', cached_diff_file) + log.exception("Failed to cleanup path %s", cached_diff_file) def _get_compression_mode(cached_diff_file): - mode = 'bz2' - if 'mode:plain' in cached_diff_file: - mode = 'plain' - elif 'mode:gzip' in cached_diff_file: - mode = 'gzip' + mode = "bz2" + if "mode:plain" in cached_diff_file: + mode = "plain" + elif "mode:gzip" in cached_diff_file: + mode = "gzip" return mode def cache_diff(cached_diff_file, diff, commits): compression_mode = _get_compression_mode(cached_diff_file) - struct = { - 'version': CURRENT_DIFF_VERSION, - 'diff': diff, - 'commits': commits - } + struct = {"version": CURRENT_DIFF_VERSION, "diff": diff, "commits": commits} start = time.time() try: - if compression_mode == 'plain': - with open(cached_diff_file, 'wb') as f: + if compression_mode == "plain": + with open(cached_diff_file, "wb") as f: pickle.dump(struct, f) - elif compression_mode == 'gzip': - with gzip.GzipFile(cached_diff_file, 'wb') as f: + elif compression_mode == "gzip": + with gzip.GzipFile(cached_diff_file, "wb") as f: pickle.dump(struct, f) else: - with bz2.BZ2File(cached_diff_file, 'wb') as f: + with bz2.BZ2File(cached_diff_file, "wb") as f: pickle.dump(struct, f) except Exception: - log.warning('Failed to save cache', exc_info=True) + log.warning("Failed to save cache", exc_info=True) _cleanup_cache_file(cached_diff_file) - log.debug('Saved diff cache under %s in %.4fs', cached_diff_file, time.time() - start) + log.debug("Saved diff cache under %s in %.4fs", cached_diff_file, time.time() - start) def load_cached_diff(cached_diff_file): compression_mode = _get_compression_mode(cached_diff_file) - default_struct = { - 'version': CURRENT_DIFF_VERSION, - 'diff': None, - 'commits': None - } + default_struct = {"version": CURRENT_DIFF_VERSION, "diff": None, "commits": None} has_cache = os.path.isfile(cached_diff_file) if not has_cache: - log.debug('Reading diff cache file failed %s', cached_diff_file) + log.debug("Reading diff cache file failed %s", cached_diff_file) return default_struct data = None start = time.time() try: - if compression_mode == 'plain': - with open(cached_diff_file, 'rb') as f: + if compression_mode == "plain": + with open(cached_diff_file, "rb") as f: data = pickle.load(f) - elif compression_mode == 'gzip': - with gzip.GzipFile(cached_diff_file, 'rb') as f: + elif compression_mode == "gzip": + with gzip.GzipFile(cached_diff_file, "rb") as f: data = pickle.load(f) else: - with bz2.BZ2File(cached_diff_file, 'rb') as f: + with bz2.BZ2File(cached_diff_file, "rb") as f: data = pickle.load(f) except Exception: - log.warning('Failed to read diff cache file', exc_info=True) + log.warning("Failed to read diff cache file", exc_info=True) if not data: data = default_struct @@ -1113,12 +1123,12 @@ def load_cached_diff(cached_diff_file): data = default_struct # check version - if data.get('version') != CURRENT_DIFF_VERSION: + if data.get("version") != CURRENT_DIFF_VERSION: # purge cache _cleanup_cache_file(cached_diff_file) return default_struct - log.debug('Loaded diff cache from %s in %.4fs', cached_diff_file, time.time() - start) + log.debug("Loaded diff cache from %s in %.4fs", cached_diff_file, time.time() - start) return data @@ -1127,26 +1137,26 @@ def generate_diff_cache_key(*args): """ Helper to generate a cache key using arguments """ + def arg_mapper(input_param): input_param = safe_str(input_param) # we cannot allow '/' in arguments since it would allow # subdirectory usage - input_param.replace('/', '_') + input_param.replace("/", "_") return input_param or None # prevent empty string arguments - return '_'.join([ - '{}' for _i in range(len(args))]).format(*list(map(arg_mapper, args))) + return "_".join(["{}" for _i in range(len(args))]).format(*list(map(arg_mapper, args))) def diff_cache_exist(cache_storage, *args): """ Based on all generated arguments check and return a cache path """ - args = list(args) + ['mode:gzip'] + args = list(args) + ["mode:gzip"] cache_key = generate_diff_cache_key(*args) cache_file_path = os.path.join(cache_storage, cache_key) # prevent path traversal attacks using some param that have e.g '../../' if not os.path.abspath(cache_file_path).startswith(cache_storage): - raise ValueError(f'Final path must be within {cache_storage}') + raise ValueError(f"Final path must be within {cache_storage}") return cache_file_path diff --git a/rhodecode/lib/enc_utils.py b/rhodecode/lib/enc_utils.py index 53633b88..2e2c3332 100644 --- a/rhodecode/lib/enc_utils.py +++ b/rhodecode/lib/enc_utils.py @@ -20,39 +20,41 @@ from rhodecode.lib.str_utils import safe_bytes from rhodecode.lib.encrypt import encrypt_data, validate_and_decrypt_data from rhodecode.lib.encrypt2 import Encryptor -ALLOWED_ALGOS = ['aes', 'fernet'] +ALLOWED_ALGOS = ["aes", "fernet"] def get_default_algo(): import rhodecode - return rhodecode.CONFIG.get('rhodecode.encrypted_values.algorithm') or 'aes' + + return rhodecode.CONFIG.get("rhodecode.encrypted_values.algorithm") or "aes" + def get_strict_mode(): import rhodecode - return rhodecode.ConfigGet().get_bool('rhodecode.encrypted_values.strict') or False + + return rhodecode.ConfigGet().get_bool("rhodecode.encrypted_values.strict") or False -def encrypt_value(value: bytes, enc_key: bytes, algo: str = ''): +def encrypt_value(value: bytes, enc_key: bytes, algo: str = ""): if not algo: # not explicit algo, just use what's set by config algo = get_default_algo() if algo not in ALLOWED_ALGOS: - ValueError(f'Bad encryption algorithm, should be {ALLOWED_ALGOS}, got: {algo}') + ValueError(f"Bad encryption algorithm, should be {ALLOWED_ALGOS}, got: {algo}") enc_key = safe_bytes(enc_key) value = safe_bytes(value) - if algo == 'aes': + if algo == "aes": return encrypt_data(value, enc_key=enc_key) - if algo == 'fernet': + if algo == "fernet": return Encryptor(enc_key).encrypt(value) return value -def decrypt_value(value: bytes, enc_key: bytes, algo: str = '', strict_mode: bool | None = None): - +def decrypt_value(value: bytes, enc_key: bytes, algo: str = "", strict_mode: bool | None = None): if strict_mode is None: # we use config value rather then explicit True/False strict_mode = get_strict_mode() @@ -64,13 +66,13 @@ def decrypt_value(value: bytes, enc_key: bytes, algo: str = '', strict_mode: boo # not explicit algo, just use what's set by config algo = Encryptor.detect_enc_algo(value) or get_default_algo() if algo not in ALLOWED_ALGOS: - ValueError(f'Bad encryption algorithm, should be {ALLOWED_ALGOS}, got: {algo}') + ValueError(f"Bad encryption algorithm, should be {ALLOWED_ALGOS}, got: {algo}") safe = not strict_mode - if algo == 'aes': + if algo == "aes": return validate_and_decrypt_data(value, enc_key, safe=safe) - if algo == 'fernet': + if algo == "fernet": return Encryptor(enc_key).decrypt(value, safe=safe) return value diff --git a/rhodecode/lib/encrypt.py b/rhodecode/lib/encrypt.py index 89149b99..9b6f80f8 100644 --- a/rhodecode/lib/encrypt.py +++ b/rhodecode/lib/encrypt.py @@ -33,26 +33,23 @@ from rhodecode.lib.exceptions import signature_verification_error class InvalidDecryptedValue(str): - def __new__(cls, content): """ This will generate something like this:: And represent a safe indicator that encryption key is broken """ - content = f'<{cls.__name__}({content[:16]}...)>' + content = f"<{cls.__name__}({content[:16]}...)>" return str.__new__(cls, content) -KEY_FORMAT = b'enc$aes_hmac${1}' +KEY_FORMAT = b"enc$aes_hmac${1}" class AESCipher(object): - def __init__(self, key: bytes, hmac=False, strict_verification=True): - if not key: - raise ValueError('passed key variable is empty') + raise ValueError("passed key variable is empty") self.strict_verification = strict_verification self.block_size = 32 self.hmac_size = 32 @@ -62,10 +59,9 @@ class AESCipher(object): self.hmac_key = SHA256.new(self.key).digest() def verify_hmac_signature(self, raw_data): - org_hmac_signature = raw_data[-self.hmac_size:] - data_without_sig = raw_data[:-self.hmac_size] - recomputed_hmac = HMAC.new( - self.hmac_key, data_without_sig, digestmod=SHA256).digest() + org_hmac_signature = raw_data[-self.hmac_size :] + data_without_sig = raw_data[: -self.hmac_size] + recomputed_hmac = HMAC.new(self.hmac_key, data_without_sig, digestmod=SHA256).digest() return org_hmac_signature == recomputed_hmac def encrypt(self, raw: bytes): @@ -74,12 +70,11 @@ class AESCipher(object): cipher = AES.new(self.key, AES.MODE_CBC, iv) enc_value = cipher.encrypt(raw) - hmac_signature = b'' + hmac_signature = b"" if self.hmac: # compute hmac+sha256 on iv + enc text, we use # encrypt then mac method to create the signature - hmac_signature = HMAC.new( - self.hmac_key, iv + enc_value, digestmod=SHA256).digest() + hmac_signature = HMAC.new(self.hmac_key, iv + enc_value, digestmod=SHA256).digest() return base64.b64encode(iv + enc_value + hmac_signature) @@ -88,63 +83,62 @@ class AESCipher(object): try: enc = base64.b64decode(enc) except Exception: - logging.exception('Failed Base64 decode') - raise signature_verification_error('Failed Base64 decode') + logging.exception("Failed Base64 decode") + raise signature_verification_error("Failed Base64 decode") if self.hmac and len(enc) > self.hmac_size: if self.verify_hmac_signature(enc): # cut off the HMAC verification digest - enc = enc[:-self.hmac_size] + enc = enc[: -self.hmac_size] else: - decrypt_fail = InvalidDecryptedValue(safe_str(enc_org)) if safe: return decrypt_fail raise signature_verification_error(decrypt_fail) - iv = enc[:AES.block_size] + iv = enc[: AES.block_size] cipher = AES.new(self.key, AES.MODE_CBC, iv) - return self._unpad(cipher.decrypt(enc[AES.block_size:])) + return self._unpad(cipher.decrypt(enc[AES.block_size :])) def _pad(self, s): - block_pad = (self.block_size - len(s) % self.block_size) + block_pad = self.block_size - len(s) % self.block_size return s + block_pad * safe_bytes(chr(block_pad)) @staticmethod def _unpad(s): - return s[:-ord(s[len(s)-1:])] + return s[: -ord(s[len(s) - 1 :])] def validate_and_decrypt_data(enc_data, enc_key, enc_strict_mode=False, safe=True): enc_data = safe_str(enc_data) - if '$' not in enc_data: + if "$" not in enc_data: # probably not encrypted values return enc_data - parts = enc_data.split('$', 3) + parts = enc_data.split("$", 3) if len(parts) != 3: - raise ValueError(f'Encrypted Data has invalid format, expected {KEY_FORMAT}, got {parts}, org value: {enc_data}') + raise ValueError( + f"Encrypted Data has invalid format, expected {KEY_FORMAT}, got {parts}, org value: {enc_data}" + ) enc_type = parts[1] enc_data_part = parts[2] - if parts[0] != 'enc': + if parts[0] != "enc": # parts ok but without our header? return enc_data # at that stage we know it's our encryption - if enc_type == 'aes': + if enc_type == "aes": decrypted_data = AESCipher(enc_key).decrypt(enc_data_part, safe=safe) - elif enc_type == 'aes_hmac': - decrypted_data = AESCipher( - enc_key, hmac=True, - strict_verification=enc_strict_mode).decrypt(enc_data_part, safe=safe) + elif enc_type == "aes_hmac": + decrypted_data = AESCipher(enc_key, hmac=True, strict_verification=enc_strict_mode).decrypt( + enc_data_part, safe=safe + ) else: - raise ValueError( - f'Encryption type part is wrong, must be `aes` ' - f'or `aes_hmac`, got `{enc_type}` instead') + raise ValueError(f"Encryption type part is wrong, must be `aes` or `aes_hmac`, got `{enc_type}` instead") return decrypted_data @@ -152,4 +146,4 @@ def validate_and_decrypt_data(enc_data, enc_key, enc_strict_mode=False, safe=Tru def encrypt_data(data, enc_key: bytes): enc_key = safe_bytes(enc_key) enc_value = AESCipher(enc_key, hmac=True).encrypt(safe_bytes(data)) - return KEY_FORMAT.replace(b'{1}', enc_value) + return KEY_FORMAT.replace(b"{1}", enc_value) diff --git a/rhodecode/lib/encrypt2.py b/rhodecode/lib/encrypt2.py index bbd4cc46..ce31d3e9 100644 --- a/rhodecode/lib/encrypt2.py +++ b/rhodecode/lib/encrypt2.py @@ -10,36 +10,35 @@ from rhodecode.lib.exceptions import signature_verification_error class InvalidDecryptedValue(str): - def __new__(cls, content): """ This will generate something like this:: And represent a safe indicator that encryption key is broken """ - content = f'<{cls.__name__}({content[:16]}...)>' + content = f"<{cls.__name__}({content[:16]}...)>" return str.__new__(cls, content) class Encryptor(object): - key_format = b'enc2$salt:{1}$data:{2}' + key_format = b"enc2$salt:{1}$data:{2}" pref_len = 5 # salt:, data: @classmethod def detect_enc_algo(cls, enc_data: bytes): - parts = enc_data.split(b'$', 3) + parts = enc_data.split(b"$", 3) - if b'enc$aes_hmac$' in enc_data: + if b"enc$aes_hmac$" in enc_data: # we expect this data is encrypted, so validate the header if len(parts) != 3: - raise ValueError(f'Encrypted Data has invalid format, expected {cls.key_format}, got `{parts}`') - return 'aes' - elif b'enc2$salt' in enc_data: + raise ValueError(f"Encrypted Data has invalid format, expected {cls.key_format}, got `{parts}`") + return "aes" + elif b"enc2$salt" in enc_data: # we expect this data is encrypted, so validate the header if len(parts) != 3: - raise ValueError(f'Encrypted Data has invalid format, expected {cls.key_format}, got `{parts}`') - return 'fernet' + raise ValueError(f"Encrypted Data has invalid format, expected {cls.key_format}, got `{parts}`") + return "fernet" return None def __init__(self, enc_key: bytes): @@ -56,36 +55,30 @@ class Encryptor(object): Uses Fernet as encryptor with HMAC signature :param salt: random salt used for encrypting the data """ - kdf = PBKDF2HMAC( - algorithm=hashes.SHA512(), - length=32, - salt=salt, - iterations=100000, - backend=default_backend() - ) + kdf = PBKDF2HMAC(algorithm=hashes.SHA512(), length=32, salt=salt, iterations=100000, backend=default_backend()) key = self.b64_encode(kdf.derive(self.enc_key)) return Fernet(key) def _get_parts(self, enc_data): - parts = enc_data.split(b'$', 3) + parts = enc_data.split(b"$", 3) if len(parts) != 3: - raise ValueError(f'Encrypted Data has invalid format, expected {self.key_format}, got `{parts}`') + raise ValueError(f"Encrypted Data has invalid format, expected {self.key_format}, got `{parts}`") prefix, salt, enc_data = parts try: - salt = self.b64_decode(salt[self.pref_len:]) + salt = self.b64_decode(salt[self.pref_len :]) except TypeError: # bad base64 - raise ValueError('Encrypted Data salt invalid format, expected base64 format') + raise ValueError("Encrypted Data salt invalid format, expected base64 format") - enc_data = enc_data[self.pref_len:] + enc_data = enc_data[self.pref_len :] return prefix, salt, enc_data def encrypt(self, data) -> bytes: salt = os.urandom(64) encryptor = self.get_encryptor(salt) enc_data = encryptor.encrypt(data) - return self.key_format.replace(b'{1}', self.b64_encode(salt)).replace(b'{2}', enc_data) + return self.key_format.replace(b"{1}", self.b64_encode(salt)).replace(b"{2}", enc_data) def decrypt(self, data, safe=True) -> bytes | InvalidDecryptedValue: parts = self._get_parts(data) diff --git a/rhodecode/lib/exc_tracking.py b/rhodecode/lib/exc_tracking.py index f50c74b2..773101d9 100644 --- a/rhodecode/lib/exc_tracking.py +++ b/rhodecode/lib/exc_tracking.py @@ -94,11 +94,8 @@ def send_exc_email(request, exc_id, exc_type_name): attach_context_attributes(TemplateArgs(), request, user_id=user_id, is_api=True) email_kwargs = { - "email_prefix": app.CONFIG.get("exception_tracker.email_prefix", "") - or "[RHODECODE ERROR]", - "exc_url": request.route_url( - "admin_settings_exception_tracker_show", exception_id=exc_id - ), + "email_prefix": app.CONFIG.get("exception_tracker.email_prefix", "") or "[RHODECODE ERROR]", + "exc_url": request.route_url("admin_settings_exception_tracker_show", exception_id=exc_id), "exc_id": exc_id, "exc_type_name": exc_type_name, "exc_traceback": read_exception(exc_id, prefix=None), @@ -123,9 +120,7 @@ def get_exc_store(): import rhodecode as app - exc_store_dir = ( - app.CONFIG.get("exception_tracker.store_path", "") or tempfile.gettempdir() - ) + exc_store_dir = app.CONFIG.get("exception_tracker.store_path", "") or tempfile.gettempdir() _exc_store_path = os.path.join(exc_store_dir, exc_store_dir_name) _exc_store_path = os.path.abspath(_exc_store_path) @@ -210,11 +205,11 @@ def format_exc(exc_info, use_detailed_tb=True): if use_detailed_tb: locals_tb = get_detailed_tb(exc_info) if locals_tb: - tb += f"\n+++ DETAILS +++\n\n{locals_tb}\n" "" + tb += f"\n+++ DETAILS +++\n\n{locals_tb}\n" return tb -def _store_exception(exc_id, exc_info, prefix, request_path='', send_email=None): +def _store_exception(exc_id, exc_info, prefix, request_path="", send_email=None): """ Low level function to store exception in the exception tracker """ @@ -238,15 +233,12 @@ def _store_exception(exc_id, exc_info, prefix, request_path='', send_email=None) log.debug("Stored generated exception %s as: %s", exc_id, stored_exc_path) if request_path: - log.error( - 'error occurred handling this request.\n' - 'Path: `%s`, %s', - request_path, tb) + log.error("error occurred handling this request.\nPath: `%s`, %s", request_path, tb) maybe_send_exc_email(exc_id, exc_type_name, send_email) -def store_exception(exc_id, exc_info, prefix=global_prefix, request_path='', send_email=None): +def store_exception(exc_id, exc_info, prefix=global_prefix, request_path="", send_email=None): """ Example usage:: @@ -259,8 +251,7 @@ def store_exception(exc_id, exc_info, prefix=global_prefix, request_path='', sen exc_type_name = exc_type.__name__ _store_exception( - exc_id=exc_id, exc_info=exc_info, prefix=prefix, request_path=request_path, - send_email=send_email + exc_id=exc_id, exc_info=exc_info, prefix=prefix, request_path=request_path, send_email=send_email ) return exc_id, exc_type_name except Exception: diff --git a/rhodecode/lib/exceptions.py b/rhodecode/lib/exceptions.py index 37f8f122..550946b6 100644 --- a/rhodecode/lib/exceptions.py +++ b/rhodecode/lib/exceptions.py @@ -92,13 +92,13 @@ class NonRelativePathError(Exception): class HTTPRequirementError(HTTPClientError): - title = explanation = 'Repository Requirement Missing' + title = explanation = "Repository Requirement Missing" reason = None def __init__(self, message, *args, **kwargs): self.title = self.explanation = message super().__init__(*args, **kwargs) - self.args = (message, ) + self.args = (message,) class HTTPLockedRepo(HTTPClientError): @@ -106,18 +106,19 @@ class HTTPLockedRepo(HTTPClientError): Special Exception For locked Repos in RhodeCode, the return code can be overwritten by _code keyword argument passed into constructors """ + code = 423 - title = explanation = 'Repository Locked' + title = explanation = "Repository Locked" reason = None def __init__(self, message, *args, **kwargs): import rhodecode - self.code = rhodecode.ConfigGet().get_int('lock_ret_code', missing=self.code) + self.code = rhodecode.ConfigGet().get_int("lock_ret_code", missing=self.code) self.title = self.explanation = message super().__init__(*args, **kwargs) - self.args = (message, ) + self.args = (message,) class HTTPBranchProtected(HTTPClientError): @@ -125,12 +126,13 @@ class HTTPBranchProtected(HTTPClientError): Special Exception For Indicating that branch is protected in RhodeCode, the return code can be overwritten by _code keyword argument passed into constructors """ - title = explanation = 'Branch Protected' + + title = explanation = "Branch Protected" reason = None class ClientNotSupported(HTTPRequirementError): - title = explanation = 'Client Not Supported' + title = explanation = "Client Not Supported" reason = None @@ -155,27 +157,27 @@ class RepositoryCreationError(Exception): class VCSServerUnavailable(HTTPBadGateway): - """ HTTP Exception class for VCS Server errors """ + """HTTP Exception class for VCS Server errors""" + code = 502 - title = 'VCS Server Error' + title = "VCS Server Error" causes = [ - 'VCS Server is not running', - 'Incorrect vcs.server=host:port', - 'Incorrect vcs.server.protocol', + "VCS Server is not running", + "Incorrect vcs.server=host:port", + "Incorrect vcs.server.protocol", ] - def __init__(self, message=''): - self.explanation = 'Could not connect to VCS Server' + def __init__(self, message=""): + self.explanation = "Could not connect to VCS Server" if message: - self.explanation += ': ' + message + self.explanation += ": " + message super().__init__() class ArtifactMetadataDuplicate(ValueError): - def __init__(self, *args, **kwargs): - self.err_section = kwargs.pop('err_section', None) - self.err_key = kwargs.pop('err_key', None) + self.err_section = kwargs.pop("err_section", None) + self.err_key = kwargs.pop("err_key", None) super().__init__(*args, **kwargs) @@ -202,6 +204,5 @@ Secret key stored inside .ini file: Probably the stored values were encrypted using a different secret then currently set in .ini file """ - final_msg = f'{msg}\n{details}' + final_msg = f"{msg}\n{details}" return SignatureVerificationError(final_msg) - diff --git a/rhodecode/lib/ext_json.py b/rhodecode/lib/ext_json.py index c86f997b..b84e6413 100644 --- a/rhodecode/lib/ext_json.py +++ b/rhodecode/lib/ext_json.py @@ -25,7 +25,7 @@ try: except ImportError: rhodecode = None -__all__ = ['json'] +__all__ = ["json"] def _obj_dump(obj): @@ -44,8 +44,8 @@ def _obj_dump(obj): r = obj.isoformat() if isinstance(obj.microsecond, int): r = r[:23] + r[26:] - if r.endswith('+00:00'): - r = r[:-6] + 'Z' + if r.endswith("+00:00"): + r = r[:-6] + "Z" return r elif isinstance(obj, datetime.date): return obj.isoformat() @@ -58,7 +58,7 @@ def _obj_dump(obj): if isinstance(obj.microsecond, int): r = r[:12] return r - elif hasattr(obj, '__json__'): + elif hasattr(obj, "__json__"): if callable(obj.__json__): return obj.__json__() else: diff --git a/rhodecode/lib/ext_json_renderer.py b/rhodecode/lib/ext_json_renderer.py index f712d86e..54db09b6 100644 --- a/rhodecode/lib/ext_json_renderer.py +++ b/rhodecode/lib/ext_json_renderer.py @@ -23,15 +23,16 @@ def pyramid_ext_json(info): """ Custom json renderer for pyramid to use our ext_json lib """ + def _render(value, system): - request = system.get('request') + request = system.get("request") indent = None if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: - response.content_type = 'application/json' - indent = getattr(request, 'ext_json_indent', None) + response.content_type = "application/json" + indent = getattr(request, "ext_json_indent", None) if indent: return ext_json.formatted_json(value) return ext_json.json.dumps(value) diff --git a/rhodecode/lib/feedgenerator/__init__.py b/rhodecode/lib/feedgenerator/__init__.py index cc5c3123..900693ef 100644 --- a/rhodecode/lib/feedgenerator/__init__.py +++ b/rhodecode/lib/feedgenerator/__init__.py @@ -16,4 +16,4 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -from .feedgenerator import Rss201rev2Feed, Atom1Feed \ No newline at end of file +from .feedgenerator import Rss201rev2Feed, Atom1Feed diff --git a/rhodecode/lib/feedgenerator/datetime_safe.py b/rhodecode/lib/feedgenerator/datetime_safe.py index e3eb3078..2998c6b0 100644 --- a/rhodecode/lib/feedgenerator/datetime_safe.py +++ b/rhodecode/lib/feedgenerator/datetime_safe.py @@ -39,10 +39,12 @@ from datetime import date as real_date, datetime as real_datetime import re import time + class date(real_date): def strftime(self, fmt): return strftime(self, fmt) + class datetime(real_datetime): def strftime(self, fmt): return strftime(self, fmt) @@ -53,10 +55,12 @@ class datetime(real_datetime): def date(self): return date(self.year, self.month, self.day) + def new_date(d): "Generate a safe date from a datetime.date object." return date(d.year, d.month, d.day) + def new_datetime(d): """ Generate a safe datetime from a datetime.date or datetime.datetime object. @@ -66,10 +70,12 @@ def new_datetime(d): kw.extend([d.hour, d.minute, d.second, d.microsecond, d.tzinfo]) return datetime(*kw) + # This library does not support strftime's "%s" or "%y" format strings. # Allowed if there's an even number of "%"s because they are escaped. _illegal_formatting = re.compile(r"((^|[^%])(%%)*%[sy])") + def _findall(text, substr): # Also finds overlaps sites = [] @@ -79,9 +85,10 @@ def _findall(text, substr): if j == -1: break sites.append(j) - i=j+1 + i = j + 1 return sites + def strftime(dt, fmt): if dt.year >= 1900: return super(type(dt), dt).strftime(fmt) @@ -102,8 +109,8 @@ def strftime(dt, fmt): s1 = time.strftime(fmt, (year,) + timetuple[1:]) sites1 = _findall(s1, str(year)) - s2 = time.strftime(fmt, (year+28,) + timetuple[1:]) - sites2 = _findall(s2, str(year+28)) + s2 = time.strftime(fmt, (year + 28,) + timetuple[1:]) + sites2 = _findall(s2, str(year + 28)) sites = [] for site in sites1: @@ -113,5 +120,5 @@ def strftime(dt, fmt): s = s1 syear = "%04d" % (dt.year,) for site in sites: - s = s[:site] + syear + s[site+4:] + s = s[:site] + syear + s[site + 4 :] return s diff --git a/rhodecode/lib/feedgenerator/feedgenerator.py b/rhodecode/lib/feedgenerator/feedgenerator.py index b4188351..2a3dca96 100644 --- a/rhodecode/lib/feedgenerator/feedgenerator.py +++ b/rhodecode/lib/feedgenerator/feedgenerator.py @@ -31,7 +31,6 @@ For definitions of the different versions of RSS, see: http://web.archive.org/web/20110718035220/http://diveintomark.org/archives/2004/02/04/incompatible-rss """ - import datetime import io @@ -47,38 +46,51 @@ from rhodecode.lib.feedgenerator.utils import SimplerXMLGenerator, iri_to_uri, f def rfc2822_date(date): # We can't use strftime() because it produces locale-dependent results, so # we have to map english month and day names manually - months = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec',) - days = ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun') + months = ( + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec", + ) + days = ("Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun") # Support datetime objects older than 1900 date = datetime_safe.new_datetime(date) # We do this ourselves to be timezone aware, email.Utils is not tz aware. dow = days[date.weekday()] month = months[date.month - 1] - time_str = date.strftime('%s, %%d %s %%Y %%H:%%M:%%S ' % (dow, month)) + time_str = date.strftime("%s, %%d %s %%Y %%H:%%M:%%S " % (dow, month)) offset = date.utcoffset() # Historically, this function assumes that naive datetimes are in UTC. if offset is None: - return time_str + '-0000' + return time_str + "-0000" else: timezone = (offset.days * 24 * 60) + (offset.seconds // 60) hour, minute = divmod(timezone, 60) - return time_str + '%+03d%02d' % (hour, minute) + return time_str + "%+03d%02d" % (hour, minute) def rfc3339_date(date): # Support datetime objects older than 1900 date = datetime_safe.new_datetime(date) - time_str = date.strftime('%Y-%m-%dT%H:%M:%S') + time_str = date.strftime("%Y-%m-%dT%H:%M:%S") offset = date.utcoffset() # Historically, this function assumes that naive datetimes are in UTC. if offset is None: - return time_str + 'Z' + return time_str + "Z" else: timezone = (offset.days * 24 * 60) + (offset.seconds // 60) hour, minute = divmod(timezone, 60) - return time_str + '%+03d:%02d' % (hour, minute) + return time_str + "%+03d:%02d" % (hour, minute) def get_tag_uri(url, date): @@ -88,56 +100,88 @@ def get_tag_uri(url, date): See http://web.archive.org/web/20110514113830/http://diveintomark.org/archives/2004/05/28/howto-atom-id """ bits = urlparse(url) - d = '' + d = "" if date is not None: - d = ',%s' % datetime_safe.new_datetime(date).strftime('%Y-%m-%d') - return 'tag:%s%s:%s/%s' % (bits.hostname, d, bits.path, bits.fragment) + d = ",%s" % datetime_safe.new_datetime(date).strftime("%Y-%m-%d") + return "tag:%s%s:%s/%s" % (bits.hostname, d, bits.path, bits.fragment) class SyndicationFeed(object): """Base class for all syndication feeds. Subclasses should provide write()""" - def __init__(self, title, link, description, language=None, author_email=None, - author_name=None, author_link=None, subtitle=None, categories=None, - feed_url=None, feed_copyright=None, feed_guid=None, ttl=None, **kwargs): + def __init__( + self, + title, + link, + description, + language=None, + author_email=None, + author_name=None, + author_link=None, + subtitle=None, + categories=None, + feed_url=None, + feed_copyright=None, + feed_guid=None, + ttl=None, + **kwargs, + ): def to_unicode(s): return force_text(s, strings_only=True) + if categories: categories = [force_text(c) for c in categories] if ttl is not None: # Force ints to unicode ttl = force_text(ttl) self.feed = { - 'title': to_unicode(title), - 'link': iri_to_uri(link), - 'description': to_unicode(description), - 'language': to_unicode(language), - 'author_email': to_unicode(author_email), - 'author_name': to_unicode(author_name), - 'author_link': iri_to_uri(author_link), - 'subtitle': to_unicode(subtitle), - 'categories': categories or (), - 'feed_url': iri_to_uri(feed_url), - 'feed_copyright': to_unicode(feed_copyright), - 'id': feed_guid or link, - 'ttl': ttl, + "title": to_unicode(title), + "link": iri_to_uri(link), + "description": to_unicode(description), + "language": to_unicode(language), + "author_email": to_unicode(author_email), + "author_name": to_unicode(author_name), + "author_link": iri_to_uri(author_link), + "subtitle": to_unicode(subtitle), + "categories": categories or (), + "feed_url": iri_to_uri(feed_url), + "feed_copyright": to_unicode(feed_copyright), + "id": feed_guid or link, + "ttl": ttl, } self.feed.update(kwargs) self.items = [] - def add_item(self, title, link, description, author_email=None, - author_name=None, author_link=None, pubdate=None, comments=None, - unique_id=None, unique_id_is_permalink=None, enclosure=None, - categories=(), item_copyright=None, ttl=None, updateddate=None, - enclosures=None, **kwargs): + def add_item( + self, + title, + link, + description, + author_email=None, + author_name=None, + author_link=None, + pubdate=None, + comments=None, + unique_id=None, + unique_id_is_permalink=None, + enclosure=None, + categories=(), + item_copyright=None, + ttl=None, + updateddate=None, + enclosures=None, + **kwargs, + ): """ Adds an item to the feed. All args are expected to be Python Unicode objects except pubdate and updateddate, which are datetime.datetime objects, and enclosures, which is an iterable of instances of the Enclosure class. """ + def to_unicode(s): return force_text(s, strings_only=True) + if categories: categories = [to_unicode(c) for c in categories] if ttl is not None: @@ -147,21 +191,21 @@ class SyndicationFeed(object): enclosures = [] if enclosures is None else enclosures item = { - 'title': to_unicode(title), - 'link': iri_to_uri(link), - 'description': to_unicode(description), - 'author_email': to_unicode(author_email), - 'author_name': to_unicode(author_name), - 'author_link': iri_to_uri(author_link), - 'pubdate': pubdate, - 'updateddate': updateddate, - 'comments': to_unicode(comments), - 'unique_id': to_unicode(unique_id), - 'unique_id_is_permalink': unique_id_is_permalink, - 'enclosures': enclosures, - 'categories': categories or (), - 'item_copyright': to_unicode(item_copyright), - 'ttl': ttl, + "title": to_unicode(title), + "link": iri_to_uri(link), + "description": to_unicode(description), + "author_email": to_unicode(author_email), + "author_name": to_unicode(author_name), + "author_link": iri_to_uri(author_link), + "pubdate": pubdate, + "updateddate": updateddate, + "comments": to_unicode(comments), + "unique_id": to_unicode(unique_id), + "unique_id_is_permalink": unique_id_is_permalink, + "enclosures": enclosures, + "categories": categories or (), + "item_copyright": to_unicode(item_copyright), + "ttl": ttl, } item.update(kwargs) self.items.append(item) @@ -200,7 +244,7 @@ class SyndicationFeed(object): Outputs the feed in the given encoding to outfile, which is a file-like object. Subclasses should override this. """ - raise NotImplementedError('subclasses of SyndicationFeed must provide a write() method') + raise NotImplementedError("subclasses of SyndicationFeed must provide a write() method") def writeString(self, encoding): """ @@ -216,7 +260,7 @@ class SyndicationFeed(object): have either of these attributes this returns the current UTC date/time. """ latest_date = None - date_keys = ('updateddate', 'pubdate') + date_keys = ("updateddate", "pubdate") for item in self.items: for date_key in date_keys: @@ -231,6 +275,7 @@ class SyndicationFeed(object): class Enclosure(object): """Represents an RSS enclosure""" + def __init__(self, url, length, mime_type): """All args are expected to be Python Unicode objects""" self.length, self.mime_type = length, mime_type @@ -238,7 +283,7 @@ class Enclosure(object): class RssFeed(SyndicationFeed): - content_type = 'application/rss+xml; charset=utf-8' + content_type = "application/rss+xml; charset=utf-8" def write(self, outfile, encoding): handler = SimplerXMLGenerator(outfile, encoding) @@ -251,30 +296,29 @@ class RssFeed(SyndicationFeed): handler.endElement("rss") def rss_attributes(self): - return {"version": self._version, - "xmlns:atom": "http://www.w3.org/2005/Atom"} + return {"version": self._version, "xmlns:atom": "http://www.w3.org/2005/Atom"} def write_items(self, handler): for item in self.items: - handler.startElement('item', self.item_attributes(item)) + handler.startElement("item", self.item_attributes(item)) self.add_item_elements(handler, item) handler.endElement("item") def add_root_elements(self, handler): - handler.addQuickElement("title", self.feed['title']) - handler.addQuickElement("link", self.feed['link']) - handler.addQuickElement("description", self.feed['description']) - if self.feed['feed_url'] is not None: - handler.addQuickElement("atom:link", None, {"rel": "self", "href": self.feed['feed_url']}) - if self.feed['language'] is not None: - handler.addQuickElement("language", self.feed['language']) - for cat in self.feed['categories']: + handler.addQuickElement("title", self.feed["title"]) + handler.addQuickElement("link", self.feed["link"]) + handler.addQuickElement("description", self.feed["description"]) + if self.feed["feed_url"] is not None: + handler.addQuickElement("atom:link", None, {"rel": "self", "href": self.feed["feed_url"]}) + if self.feed["language"] is not None: + handler.addQuickElement("language", self.feed["language"]) + for cat in self.feed["categories"]: handler.addQuickElement("category", cat) - if self.feed['feed_copyright'] is not None: - handler.addQuickElement("copyright", self.feed['feed_copyright']) + if self.feed["feed_copyright"] is not None: + handler.addQuickElement("copyright", self.feed["feed_copyright"]) handler.addQuickElement("lastBuildDate", rfc2822_date(self.latest_post_date())) - if self.feed['ttl'] is not None: - handler.addQuickElement("ttl", self.feed['ttl']) + if self.feed["ttl"] is not None: + handler.addQuickElement("ttl", self.feed["ttl"]) def endChannelElement(self, handler): handler.endElement("channel") @@ -284,10 +328,10 @@ class RssUserland091Feed(RssFeed): _version = "0.91" def add_item_elements(self, handler, item): - handler.addQuickElement("title", item['title']) - handler.addQuickElement("link", item['link']) - if item['description'] is not None: - handler.addQuickElement("description", item['description']) + handler.addQuickElement("title", item["title"]) + handler.addQuickElement("link", item["link"]) + if item["description"] is not None: + handler.addQuickElement("description", item["description"]) class Rss201rev2Feed(RssFeed): @@ -295,93 +339,95 @@ class Rss201rev2Feed(RssFeed): _version = "2.0" def add_item_elements(self, handler, item): - handler.addQuickElement("title", item['title']) - handler.addQuickElement("link", item['link']) - if item['description'] is not None: - handler.addQuickElement("description", item['description']) + handler.addQuickElement("title", item["title"]) + handler.addQuickElement("link", item["link"]) + if item["description"] is not None: + handler.addQuickElement("description", item["description"]) # Author information. if item["author_name"] and item["author_email"]: - handler.addQuickElement("author", "%s (%s)" % (item['author_email'], item['author_name'])) + handler.addQuickElement("author", "%s (%s)" % (item["author_email"], item["author_name"])) elif item["author_email"]: handler.addQuickElement("author", item["author_email"]) elif item["author_name"]: - handler.addQuickElement( - "dc:creator", item["author_name"], {"xmlns:dc": "http://purl.org/dc/elements/1.1/"} - ) + handler.addQuickElement("dc:creator", item["author_name"], {"xmlns:dc": "http://purl.org/dc/elements/1.1/"}) - if item['pubdate'] is not None: - handler.addQuickElement("pubDate", rfc2822_date(item['pubdate'])) - if item['comments'] is not None: - handler.addQuickElement("comments", item['comments']) - if item['unique_id'] is not None: + if item["pubdate"] is not None: + handler.addQuickElement("pubDate", rfc2822_date(item["pubdate"])) + if item["comments"] is not None: + handler.addQuickElement("comments", item["comments"]) + if item["unique_id"] is not None: guid_attrs = {} - if isinstance(item.get('unique_id_is_permalink'), bool): - guid_attrs['isPermaLink'] = str(item['unique_id_is_permalink']).lower() - handler.addQuickElement("guid", item['unique_id'], guid_attrs) - if item['ttl'] is not None: - handler.addQuickElement("ttl", item['ttl']) + if isinstance(item.get("unique_id_is_permalink"), bool): + guid_attrs["isPermaLink"] = str(item["unique_id_is_permalink"]).lower() + handler.addQuickElement("guid", item["unique_id"], guid_attrs) + if item["ttl"] is not None: + handler.addQuickElement("ttl", item["ttl"]) # Enclosure. - if item['enclosures']: - enclosures = list(item['enclosures']) + if item["enclosures"]: + enclosures = list(item["enclosures"]) if len(enclosures) > 1: raise ValueError( "RSS feed items may only have one enclosure, see " "http://www.rssboard.org/rss-profile#element-channel-item-enclosure" ) enclosure = enclosures[0] - handler.addQuickElement('enclosure', '', { - 'url': enclosure.url, - 'length': enclosure.length, - 'type': enclosure.mime_type, - }) + handler.addQuickElement( + "enclosure", + "", + { + "url": enclosure.url, + "length": enclosure.length, + "type": enclosure.mime_type, + }, + ) # Categories. - for cat in item['categories']: + for cat in item["categories"]: handler.addQuickElement("category", cat) class Atom1Feed(SyndicationFeed): # Spec: https://tools.ietf.org/html/rfc4287 - content_type = 'application/atom+xml; charset=utf-8' + content_type = "application/atom+xml; charset=utf-8" ns = "http://www.w3.org/2005/Atom" def write(self, outfile, encoding): handler = SimplerXMLGenerator(outfile, encoding) handler.startDocument() - handler.startElement('feed', self.root_attributes()) + handler.startElement("feed", self.root_attributes()) self.add_root_elements(handler) self.write_items(handler) handler.endElement("feed") def root_attributes(self): - if self.feed['language'] is not None: - return {"xmlns": self.ns, "xml:lang": self.feed['language']} + if self.feed["language"] is not None: + return {"xmlns": self.ns, "xml:lang": self.feed["language"]} else: return {"xmlns": self.ns} def add_root_elements(self, handler): - handler.addQuickElement("title", self.feed['title']) - handler.addQuickElement("link", "", {"rel": "alternate", "href": self.feed['link']}) - if self.feed['feed_url'] is not None: - handler.addQuickElement("link", "", {"rel": "self", "href": self.feed['feed_url']}) - handler.addQuickElement("id", self.feed['id']) + handler.addQuickElement("title", self.feed["title"]) + handler.addQuickElement("link", "", {"rel": "alternate", "href": self.feed["link"]}) + if self.feed["feed_url"] is not None: + handler.addQuickElement("link", "", {"rel": "self", "href": self.feed["feed_url"]}) + handler.addQuickElement("id", self.feed["id"]) handler.addQuickElement("updated", rfc3339_date(self.latest_post_date())) - if self.feed['author_name'] is not None: + if self.feed["author_name"] is not None: handler.startElement("author", {}) - handler.addQuickElement("name", self.feed['author_name']) - if self.feed['author_email'] is not None: - handler.addQuickElement("email", self.feed['author_email']) - if self.feed['author_link'] is not None: - handler.addQuickElement("uri", self.feed['author_link']) + handler.addQuickElement("name", self.feed["author_name"]) + if self.feed["author_email"] is not None: + handler.addQuickElement("email", self.feed["author_email"]) + if self.feed["author_link"] is not None: + handler.addQuickElement("uri", self.feed["author_link"]) handler.endElement("author") - if self.feed['subtitle'] is not None: - handler.addQuickElement("subtitle", self.feed['subtitle']) - for cat in self.feed['categories']: + if self.feed["subtitle"] is not None: + handler.addQuickElement("subtitle", self.feed["subtitle"]) + for cat in self.feed["categories"]: handler.addQuickElement("category", "", {"term": cat}) - if self.feed['feed_copyright'] is not None: - handler.addQuickElement("rights", self.feed['feed_copyright']) + if self.feed["feed_copyright"] is not None: + handler.addQuickElement("rights", self.feed["feed_copyright"]) def write_items(self, handler): for item in self.items: @@ -390,54 +436,58 @@ class Atom1Feed(SyndicationFeed): handler.endElement("entry") def add_item_elements(self, handler, item): - handler.addQuickElement("title", item['title']) - handler.addQuickElement("link", "", {"href": item['link'], "rel": "alternate"}) + handler.addQuickElement("title", item["title"]) + handler.addQuickElement("link", "", {"href": item["link"], "rel": "alternate"}) - if item['pubdate'] is not None: - handler.addQuickElement('published', rfc3339_date(item['pubdate'])) + if item["pubdate"] is not None: + handler.addQuickElement("published", rfc3339_date(item["pubdate"])) - if item['updateddate'] is not None: - handler.addQuickElement('updated', rfc3339_date(item['updateddate'])) + if item["updateddate"] is not None: + handler.addQuickElement("updated", rfc3339_date(item["updateddate"])) # Author information. - if item['author_name'] is not None: + if item["author_name"] is not None: handler.startElement("author", {}) - handler.addQuickElement("name", item['author_name']) - if item['author_email'] is not None: - handler.addQuickElement("email", item['author_email']) - if item['author_link'] is not None: - handler.addQuickElement("uri", item['author_link']) + handler.addQuickElement("name", item["author_name"]) + if item["author_email"] is not None: + handler.addQuickElement("email", item["author_email"]) + if item["author_link"] is not None: + handler.addQuickElement("uri", item["author_link"]) handler.endElement("author") # Unique ID. - if item['unique_id'] is not None: - unique_id = item['unique_id'] + if item["unique_id"] is not None: + unique_id = item["unique_id"] else: - unique_id = get_tag_uri(item['link'], item['pubdate']) + unique_id = get_tag_uri(item["link"], item["pubdate"]) handler.addQuickElement("id", unique_id) # Summary. - if item['description'] is not None: - handler.addQuickElement("summary", item['description'], {"type": "html"}) + if item["description"] is not None: + handler.addQuickElement("summary", item["description"], {"type": "html"}) # Enclosures. - for enclosure in item['enclosures']: - handler.addQuickElement('link', '', { - 'rel': 'enclosure', - 'href': enclosure.url, - 'length': enclosure.length, - 'type': enclosure.mime_type, - }) + for enclosure in item["enclosures"]: + handler.addQuickElement( + "link", + "", + { + "rel": "enclosure", + "href": enclosure.url, + "length": enclosure.length, + "type": enclosure.mime_type, + }, + ) # Categories. - for cat in item['categories']: + for cat in item["categories"]: handler.addQuickElement("category", "", {"term": cat}) # Rights. - if item['item_copyright'] is not None: - handler.addQuickElement("rights", item['item_copyright']) + if item["item_copyright"] is not None: + handler.addQuickElement("rights", item["item_copyright"]) # This isolates the decision of what the system default is, so calling code can # do "feedgenerator.DefaultFeed" instead of "feedgenerator.Rss201rev2Feed". -DefaultFeed = Rss201rev2Feed \ No newline at end of file +DefaultFeed = Rss201rev2Feed diff --git a/rhodecode/lib/feedgenerator/utils.py b/rhodecode/lib/feedgenerator/utils.py index 6845b3ef..6f08ff33 100644 --- a/rhodecode/lib/feedgenerator/utils.py +++ b/rhodecode/lib/feedgenerator/utils.py @@ -20,11 +20,11 @@ class SimplerXMLGenerator(XMLGenerator): self.endElement(name) def startElement(self, name, attrs): - self._write('<' + name) + self._write("<" + name) # sort attributes for consistent output - for (name, value) in sorted(attrs.items()): - self._write(' {}={}'.format(name, quoteattr(value))) - self._write('>') + for name, value in sorted(attrs.items()): + self._write(" {}={}".format(name, quoteattr(value))) + self._write(">") def iri_to_uri(iri): diff --git a/rhodecode/lib/graphmod.py b/rhodecode/lib/graphmod.py index 5651cb6d..463da5e2 100644 --- a/rhodecode/lib/graphmod.py +++ b/rhodecode/lib/graphmod.py @@ -52,27 +52,24 @@ def _dagwalker(repo, commits): def get_parent_indexes(idx): return [commit.idx for commit in repo[idx].parents] - indexes = [commit['idx'] for commit in commits] + indexes = [commit["idx"] for commit in commits] lowest_idx = min(indexes) known_indexes = set(indexes) grandparnet_cache = {} for commit in commits: - parents = sorted(set([p['idx'] for p in commit['parents'] - if p['idx'] in known_indexes])) - mpars = [p['idx'] for p in commit['parents'] if - p['idx'] != nullrev and p['idx'] not in parents] + parents = sorted(set([p["idx"] for p in commit["parents"] if p["idx"] in known_indexes])) + mpars = [p["idx"] for p in commit["parents"] if p["idx"] != nullrev and p["idx"] not in parents] for mpar in mpars: gp = grandparnet_cache.get(mpar) if gp is None: - gp = grandparnet_cache[mpar] = grandparent( - get_parent_indexes, lowest_idx, indexes, mpar) + gp = grandparnet_cache[mpar] = grandparent(get_parent_indexes, lowest_idx, indexes, mpar) if not gp: parents.append(mpar) else: parents.extend(g for g in gp if g not in parents) - yield (commit['raw_id'], commit['idx'], parents, commit['branch']) + yield (commit["raw_id"], commit["idx"], parents, commit["branch"]) def _colored(dag): @@ -93,7 +90,6 @@ def _colored(dag): newcolor = 1 for commit_id, commit_idx, parents, branch in dag: - # Compute seen and next_ if commit_idx not in seen: seen.append(commit_idx) # new head @@ -106,7 +102,7 @@ def _colored(dag): # Add parents to next_ addparents = [p for p in parents if p not in next_] - next_[col:col + 1] = addparents + next_[col : col + 1] = addparents # Set colors for the parents for i, p in enumerate(addparents): @@ -123,10 +119,9 @@ def _colored(dag): edges.append((ecol, next_.index(eid), colors[eid])) elif eid == commit_idx: total_parents = len(parents) - edges.extend([ - (ecol, next_.index(p), - _get_edge_color(p, total_parents, color, colors)) - for p in parents]) + edges.extend( + [(ecol, next_.index(p), _get_edge_color(p, total_parents, color, colors)) for p in parents] + ) # Yield and move on yield (commit_id, (col, color), edges, branch) diff --git a/rhodecode/lib/hash_utils.py b/rhodecode/lib/hash_utils.py index 682337fe..d1cdc67d 100644 --- a/rhodecode/lib/hash_utils.py +++ b/rhodecode/lib/hash_utils.py @@ -24,10 +24,9 @@ def md5(s): return hashlib.md5(s).hexdigest() -def md5_safe(s, return_type=''): - +def md5_safe(s, return_type=""): val = md5(safe_bytes(s)) - if return_type == 'str': + if return_type == "str": val = safe_str(val) return val @@ -36,9 +35,9 @@ def sha1(s): return hashlib.sha1(s).hexdigest() -def sha1_safe(s, return_type=''): +def sha1_safe(s, return_type=""): val = sha1(safe_bytes(s)) - if return_type == 'str': + if return_type == "str": val = safe_str(val) return val @@ -47,8 +46,8 @@ def sha256(s): return hashlib.sha256(s).hexdigest() -def sha256_safe(s, return_type=''): +def sha256_safe(s, return_type=""): val = sha256(safe_bytes(s)) - if return_type == 'str': + if return_type == "str": val = safe_str(val) return val diff --git a/rhodecode/lib/helpers.py b/rhodecode/lib/helpers.py index 1283a71c..328fd5bf 100644 --- a/rhodecode/lib/helpers.py +++ b/rhodecode/lib/helpers.py @@ -481,7 +481,7 @@ class CodeHtmlFormatter(HtmlFormatter): def _wrap_code(self, source): for cnt, it in enumerate(source): i, t = it - t = f'
{t}
' + t = f'
{t}
' yield i, t def _wrap_tablelinenos(self, inner): @@ -1865,9 +1865,7 @@ def _process_url_func(match_obj, repo_name, uid, entry, return_raw_data=False, l issue_id = "".join(match_obj.groups()) if link_format == "html": - tmpl = ( - '%(pref)s' "%(issue-prefix)s%(id-repr)s" "" - ) + tmpl = '%(pref)s%(issue-prefix)s%(id-repr)s' elif link_format == "html+hovercard": tmpl = ( '%(pref)s' diff --git a/rhodecode/lib/hook_daemon/base.py b/rhodecode/lib/hook_daemon/base.py index d0629edb..7bf9f511 100644 --- a/rhodecode/lib/hook_daemon/base.py +++ b/rhodecode/lib/hook_daemon/base.py @@ -32,22 +32,24 @@ class BaseHooksCallbackDaemon: """ Basic context manager for actions that don't require some extra """ + def __init__(self): pass def __enter__(self): - log.debug('Running `%s` callback daemon', self.__class__.__name__) + log.debug("Running `%s` callback daemon", self.__class__.__name__) return self def __exit__(self, exc_type, exc_val, exc_tb): - log.debug('Exiting `%s` callback daemon', self.__class__.__name__) + log.debug("Exiting `%s` callback daemon", self.__class__.__name__) class Hooks(object): """ Exposes the hooks module for calling them using the local HooksModuleCallbackDaemon """ - def __init__(self, request=None, log_prefix=''): + + def __init__(self, request=None, log_prefix=""): self.log_prefix = log_prefix self.request = request @@ -73,47 +75,41 @@ class Hooks(object): def _call_hook(self, hook, extras): extras = AttributeDict(extras) - _server_url = extras['server_url'] + _server_url = extras["server_url"] extras.request = self.request try: result = hook(extras) if result is None: - raise Exception(f'Failed to obtain hook result from func: {hook}') + raise Exception(f"Failed to obtain hook result from func: {hook}") except HTTPBranchProtected as error: # Those special cases don't need error reporting. It's a case of # locked repo or protected branch - result = AttributeDict({ - 'status': error.code, - 'output': error.explanation - }) + result = AttributeDict({"status": error.code, "output": error.explanation}) except HTTPLockedRepo as error: # Those special cases don't need error reporting. It's a case of # locked repo or protected branch - result = AttributeDict({ - 'status': error.code, - 'output': error.explanation - }) + result = AttributeDict({"status": error.code, "output": error.explanation}) except Exception as error: # locked needs different handling since we need to also # handle PULL operations - log.exception('%sException when handling hook %s', self.log_prefix, hook) + log.exception("%sException when handling hook %s", self.log_prefix, hook) exc_tb = traceback.format_exc() error_args = error.args return { - 'status': 128, - 'output': '', - 'exception': type(error).__name__, - 'exception_traceback': exc_tb, - 'exception_args': error_args, + "status": 128, + "output": "", + "exception": type(error).__name__, + "exception_traceback": exc_tb, + "exception_args": error_args, } finally: meta.Session.remove() - log.debug('%sGot hook call response %s', self.log_prefix, result) + log.debug("%sGot hook call response %s", self.log_prefix, result) return { - 'status': result.status, - 'output': result.output, + "status": result.status, + "output": result.output, } def __enter__(self): @@ -121,4 +117,3 @@ class Hooks(object): def __exit__(self, exc_type, exc_val, exc_tb): pass - diff --git a/rhodecode/lib/hook_daemon/celery_hooks_deamon.py b/rhodecode/lib/hook_daemon/celery_hooks_deamon.py index 19cb5991..064e9e0b 100644 --- a/rhodecode/lib/hook_daemon/celery_hooks_deamon.py +++ b/rhodecode/lib/hook_daemon/celery_hooks_deamon.py @@ -34,4 +34,4 @@ class CeleryHooksCallbackDaemon(BaseHooksCallbackDaemon): self.result_backend = result_backend def __repr__(self): - return f'CeleryHooksCallbackDaemon(broker_url={self.broker_url}, result_backend={self.result_backend})' + return f"CeleryHooksCallbackDaemon(broker_url={self.broker_url}, result_backend={self.result_backend})" diff --git a/rhodecode/lib/hook_daemon/hook_module.py b/rhodecode/lib/hook_daemon/hook_module.py index ea7e484e..cc98b8e9 100644 --- a/rhodecode/lib/hook_daemon/hook_module.py +++ b/rhodecode/lib/hook_daemon/hook_module.py @@ -24,11 +24,9 @@ log = logging.getLogger(__name__) class HooksModuleCallbackDaemon(BaseHooksCallbackDaemon): - def __init__(self, module): super().__init__() self.hooks_module = module def __repr__(self): - return f'HooksModuleCallbackDaemon(hooks_module={self.hooks_module})' - + return f"HooksModuleCallbackDaemon(hooks_module={self.hooks_module})" diff --git a/rhodecode/lib/hook_daemon/utils.py b/rhodecode/lib/hook_daemon/utils.py index b2938e21..33d44099 100644 --- a/rhodecode/lib/hook_daemon/utils.py +++ b/rhodecode/lib/hook_daemon/utils.py @@ -29,33 +29,32 @@ from rhodecode.lib.type_utils import str2bool log = logging.getLogger(__name__) - def prepare_callback_daemon(extras, protocol: str, txn_id=None): hooks_config = {} match protocol: - case 'celery': - config = get_app_config_lightweight(extras['config']) + case "celery": + config = get_app_config_lightweight(extras["config"]) - broker_url = config.get('celery.broker_url') - result_backend = config.get('celery.result_backend') + broker_url = config.get("celery.broker_url") + result_backend = config.get("celery.result_backend") hooks_config = { - 'broker_url': broker_url, - 'result_backend': result_backend, + "broker_url": broker_url, + "result_backend": result_backend, } callback_daemon = CeleryHooksCallbackDaemon(broker_url, result_backend) - case 'local': + case "local": callback_daemon = HooksModuleCallbackDaemon(Hooks.__module__) case _: log.error('Unsupported callback daemon protocol "%s"', protocol) - raise Exception('Unsupported callback daemon protocol.') + raise Exception("Unsupported callback daemon protocol.") - extras['hooks_config'] = hooks_config - extras['hooks_protocol'] = protocol - extras['time'] = time.time() + extras["hooks_config"] = hooks_config + extras["hooks_protocol"] = protocol + extras["time"] = time.time() # register txn_id - extras['txn_id'] = txn_id - log.debug('Prepared a callback daemon: %s', callback_daemon.__class__.__name__) + extras["txn_id"] = txn_id + log.debug("Prepared a callback daemon: %s", callback_daemon.__class__.__name__) return callback_daemon, extras diff --git a/rhodecode/lib/hooks_base.py b/rhodecode/lib/hooks_base.py index bb10ee9f..fdd3d8ff 100644 --- a/rhodecode/lib/hooks_base.py +++ b/rhodecode/lib/hooks_base.py @@ -29,8 +29,7 @@ from rhodecode import events from rhodecode.lib import helpers as h from rhodecode.lib import audit_logger from rhodecode.lib.utils2 import safe_str, user_agent_normalizer -from rhodecode.lib.exceptions import ( - HTTPLockedRepo, HTTPBranchProtected, UserCreationError, ClientNotSupported) +from rhodecode.lib.exceptions import HTTPLockedRepo, HTTPBranchProtected, UserCreationError, ClientNotSupported from rhodecode.model.db import Repository, User from rhodecode.lib.statsd_client import StatsdClient @@ -43,9 +42,9 @@ class HookResponse: self.output = output def __add__(self, other): - other_status = getattr(other, 'status', 0) + other_status = getattr(other, "status", 0) new_status = max(self.status, other_status) - other_output = getattr(other, 'output', '') + other_output = getattr(other, "output", "") new_output = self.output + other_output return HookResponse(new_status, new_output) @@ -54,16 +53,17 @@ class HookResponse: return self.status == 0 def to_json(self): - return {'status': self.status, 'output': self.output} + return {"status": self.status, "output": self.output} def __repr__(self): return self.to_json().__repr__() + def is_shadow_repo(extras): """ Returns ``True`` if this is an action executed against a shadow repository. """ - return extras['is_shadow_repo'] + return extras["is_shadow_repo"] def check_vcs_client(extras): @@ -74,22 +74,22 @@ def check_vcs_client(extras): from rc_ee.lib.security.utils import is_vcs_client_whitelisted except ModuleNotFoundError: is_vcs_client_whitelisted = lambda *x: True - backend = extras.get('scm') - user_agent = extras.get('user_agent') + backend = extras.get("scm") + user_agent = extras.get("user_agent") if not is_vcs_client_whitelisted(user_agent, backend): raise ClientNotSupported(f"Your {backend} client (version={user_agent}) is forbidden by security rules") def check_locked_repo(extras, check_same_user=True): user = User.get_by_username(extras.username) - output = '' + output = "" if extras.locked_by[0] and (not check_same_user or user.user_id != extras.locked_by[0]): locked_by = User.get(extras.locked_by[0]).username reason = extras.locked_by[2] # this exception is interpreted in git/hg middlewares and based # on that proper return code is server to client _http_ret = HTTPLockedRepo(_locked_by_explanation(extras.repository, locked_by, reason)) - if str(_http_ret.code).startswith('2'): + if str(_http_ret.code).startswith("2"): # 2xx Codes don't raise exceptions output = _http_ret.title else: @@ -104,44 +104,42 @@ def check_branch_protected(extras): auth_user = user.AuthUser() repo = Repository.get_by_repo_name(extras.repository) if not repo: - raise ValueError(f'Repo for {extras.repository} not found') + raise ValueError(f"Repo for {extras.repository} not found") affected_branches = [] - if repo.repo_type == 'hg': + if repo.repo_type == "hg": for entry in extras.commit_ids: - if entry['type'] == 'branch': - is_forced = bool(entry['multiple_heads']) - affected_branches.append([entry['name'], is_forced]) - elif repo.repo_type == 'git': + if entry["type"] == "branch": + is_forced = bool(entry["multiple_heads"]) + affected_branches.append([entry["name"], is_forced]) + elif repo.repo_type == "git": for entry in extras.commit_ids: - if entry['type'] == 'heads': - is_forced = bool(entry['pruned_sha']) - affected_branches.append([entry['name'], is_forced]) + if entry["type"] == "heads": + is_forced = bool(entry["pruned_sha"]) + affected_branches.append([entry["name"], is_forced]) for branch_name, is_forced in affected_branches: - rule, branch_perm = auth_user.get_rule_and_branch_permission(extras.repository, branch_name) if not branch_perm: # no branch permission found for this branch, just keep checking continue - if branch_perm == 'branch.push_force': + if branch_perm == "branch.push_force": continue - elif branch_perm == 'branch.push' and is_forced is False: + elif branch_perm == "branch.push" and is_forced is False: continue - elif branch_perm == 'branch.push' and is_forced is True: - halt_message = f'Branch `{branch_name}` changes rejected by rule {rule}. ' \ - f'FORCE PUSH FORBIDDEN.' + elif branch_perm == "branch.push" and is_forced is True: + halt_message = f"Branch `{branch_name}` changes rejected by rule {rule}. FORCE PUSH FORBIDDEN." else: - halt_message = f'Branch `{branch_name}` changes rejected by rule {rule}.' + halt_message = f"Branch `{branch_name}` changes rejected by rule {rule}." if halt_message: _http_ret = HTTPBranchProtected(halt_message) raise _http_ret -def _get_scm_size(alias, root_path): - if not alias.startswith('.'): - alias += '.' +def _get_scm_size(alias, root_path): + if not alias.startswith("."): + alias += "." size_scm, size_root = 0, 0 for path, unused_dirs, files in os.walk(safe_str(root_path)): @@ -169,9 +167,9 @@ def _get_scm_size(alias, root_path): def repo_size(extras): """Present size of repository after push.""" repo = Repository.get_by_repo_name(extras.repository) - vcs_part = f'.{repo.repo_type}' + vcs_part = f".{repo.repo_type}" size_vcs, size_root, size_total = _get_scm_size(vcs_part, repo.repo_full_path) - msg = f'RhodeCode: `{repo.repo_name}` size summary {vcs_part}:{size_vcs} repo:{size_root} total:{size_total}\n' + msg = f"RhodeCode: `{repo.repo_name}` size summary {vcs_part}:{size_vcs} repo:{size_root} total:{size_total}\n" return HookResponse(0, msg) @@ -182,7 +180,7 @@ def pre_pull(extras): It bans pulling when the repository is locked. It bans pulling when incorrect client is used. """ - output = '' + output = "" check_vcs_client(extras) # locking repo can, but not have to stop the operation it can also just produce output @@ -190,9 +188,9 @@ def pre_pull(extras): # Propagate to external components. This is done after checking the # lock, for consistent behavior. - hook_response = '' + hook_response = "" if not is_shadow_repo(extras): - extras.hook_type = extras.hook_type or 'pre_pull' + extras.hook_type = extras.hook_type or "pre_pull" hook_response = pre_pull_extension(repo_store_path=Repository.base_path(), **extras) events.trigger(events.RepoPrePullEvent(repo_name=extras.repository, extras=extras)) @@ -202,38 +200,35 @@ def pre_pull(extras): def post_pull(extras): """Hook executed after client pulls the code.""" - audit_user = audit_logger.UserWrap( - username=extras.username, - ip_addr=extras.ip) + audit_user = audit_logger.UserWrap(username=extras.username, ip_addr=extras.ip) repo = audit_logger.RepoWrap(repo_name=extras.repository) audit_logger.store( - 'user.pull', action_data={'user_agent': extras.user_agent}, - user=audit_user, repo=repo, commit=True) + "user.pull", action_data={"user_agent": extras.user_agent}, user=audit_user, repo=repo, commit=True + ) statsd = StatsdClient.statsd if statsd: - statsd.incr('rhodecode_pull_total', tags=[ - f'user-agent:{user_agent_normalizer(extras.user_agent)}', - ]) + statsd.incr( + "rhodecode_pull_total", + tags=[ + f"user-agent:{user_agent_normalizer(extras.user_agent)}", + ], + ) - output = '' + output = "" # make lock is a tri state False, True, None. We only make lock on True if extras.make_lock is True and not is_shadow_repo(extras): user = User.get_by_username(extras.username) - Repository.lock(Repository.get_by_repo_name(extras.repository), - user.user_id, - lock_reason=Repository.LOCK_PULL) - msg = f'Made lock on repo `{extras.repository}`' + Repository.lock(Repository.get_by_repo_name(extras.repository), user.user_id, lock_reason=Repository.LOCK_PULL) + msg = f"Made lock on repo `{extras.repository}`" output += msg # Propagate to external components. - hook_response = '' + hook_response = "" if not is_shadow_repo(extras): - extras.hook_type = extras.hook_type or 'post_pull' - hook_response = post_pull_extension( - repo_store_path=Repository.base_path(), **extras) - events.trigger(events.RepoPullEvent( - repo_name=extras.repository, extras=extras)) + extras.hook_type = extras.hook_type or "post_pull" + hook_response = post_pull_extension(repo_store_path=Repository.base_path(), **extras) + events.trigger(events.RepoPullEvent(repo_name=extras.repository, extras=extras)) return HookResponse(0, output) + hook_response @@ -246,15 +241,14 @@ def pre_push(extras): It banks pushing when incorrect client is used. It also checks for Branch protection """ - output = '' + output = "" check_vcs_client(extras) # locking repo can, but not have to stop the operation it can also just produce output output += check_locked_repo(extras) - hook_response = '' + hook_response = "" if not is_shadow_repo(extras): - check_branch_protected(extras) # Propagate to external components. This is done after checking the @@ -270,53 +264,58 @@ def post_push(extras): commit_ids = extras.commit_ids # log the push call - audit_user = audit_logger.UserWrap( - username=extras.username, ip_addr=extras.ip) + audit_user = audit_logger.UserWrap(username=extras.username, ip_addr=extras.ip) repo = audit_logger.RepoWrap(repo_name=extras.repository) audit_logger.store( - 'user.push', action_data={ - 'user_agent': extras.user_agent, - 'commit_ids': commit_ids[:400]}, - user=audit_user, repo=repo, commit=True) + "user.push", + action_data={"user_agent": extras.user_agent, "commit_ids": commit_ids[:400]}, + user=audit_user, + repo=repo, + commit=True, + ) statsd = StatsdClient.statsd if statsd: - statsd.incr('rhodecode_push_total', tags=[ - f'user-agent:{user_agent_normalizer(extras.user_agent)}', - ]) + statsd.incr( + "rhodecode_push_total", + tags=[ + f"user-agent:{user_agent_normalizer(extras.user_agent)}", + ], + ) # Propagate to external components. - output = '' + output = "" # make lock is a tri state False, True, None. We only release lock on False if extras.make_lock is False and not is_shadow_repo(extras): Repository.unlock(Repository.get_by_repo_name(extras.repository)) - msg = f'Released lock on repo `{extras.repository}`\n' + msg = f"Released lock on repo `{extras.repository}`\n" output += msg if extras.new_refs: - tmpl = '{}/{}/pull-request/new?{{ref_type}}={{ref_name}}'.format( - safe_str(extras.server_url), safe_str(extras.repository)) + tmpl = "{}/{}/pull-request/new?{{ref_type}}={{ref_name}}".format( + safe_str(extras.server_url), safe_str(extras.repository) + ) - for branch_name in extras.new_refs['branches']: - pr_link = tmpl.format(ref_type='branch', ref_name=safe_str(branch_name)) - output += f'RhodeCode: open pull request link: {pr_link}\n' + for branch_name in extras.new_refs["branches"]: + pr_link = tmpl.format(ref_type="branch", ref_name=safe_str(branch_name)) + output += f"RhodeCode: open pull request link: {pr_link}\n" - for book_name in extras.new_refs['bookmarks']: - pr_link = tmpl.format(ref_type='bookmark', ref_name=safe_str(book_name)) - output += f'RhodeCode: open pull request link: {pr_link}\n' + for book_name in extras.new_refs["bookmarks"]: + pr_link = tmpl.format(ref_type="bookmark", ref_name=safe_str(book_name)) + output += f"RhodeCode: open pull request link: {pr_link}\n" - hook_response = '' + hook_response = "" if not is_shadow_repo(extras): hook_response = post_push_extension(repo_store_path=Repository.base_path(), **extras) events.trigger(events.RepoPushEvent(repo_name=extras.repository, pushed_commit_ids=commit_ids, extras=extras)) - output += 'RhodeCode: push completed\n' + output += "RhodeCode: push completed\n" return HookResponse(0, output) + hook_response def _locked_by_explanation(repo_name, user_name, reason): - message = f'Repository `{repo_name}` locked by user `{user_name}`. Reason:`{reason}`' + message = f"Repository `{repo_name}` locked by user `{user_name}`. Reason:`{reason}`" return message @@ -344,10 +343,10 @@ class ExtensionCallback(object): self._kwargs_keys = set(kwargs_keys) def __call__(self, *args, **kwargs): - log.debug('Calling extension callback for `%s`', self._hook_name) + log.debug("Calling extension callback for `%s`", self._hook_name) callback = self._get_callback() if not callback: - log.debug('extension callback `%s` not found, skipping...', self._hook_name) + log.debug("extension callback `%s` not found, skipping...", self._hook_name) return kwargs_to_pass = {} @@ -355,16 +354,15 @@ class ExtensionCallback(object): try: kwargs_to_pass[key] = kwargs[key] except KeyError: - log.error('Failed to fetch %s key from given kwargs. ' - 'Expected keys: %s', key, self._kwargs_keys) + log.error("Failed to fetch %s key from given kwargs. Expected keys: %s", key, self._kwargs_keys) raise # backward compat for removed api_key for old hooks. This was it works # with older rcextensions that require api_key present - if self._hook_name in ['CREATE_USER_HOOK', 'DELETE_USER_HOOK']: - kwargs_to_pass['api_key'] = '_DEPRECATED_' + if self._hook_name in ["CREATE_USER_HOOK", "DELETE_USER_HOOK"]: + kwargs_to_pass["api_key"] = "_DEPRECATED_" result = callback(**kwargs_to_pass) - log.debug('got rcextensions result: %s', result) + log.debug("got rcextensions result: %s", result) return result def is_active(self): @@ -372,170 +370,439 @@ class ExtensionCallback(object): def _get_callback(self): if rhodecode.is_test: - log.debug('In test mode, reloading rcextensions...') + log.debug("In test mode, reloading rcextensions...") # NOTE: for test re-load rcextensions always so we can dynamically change them for testing purposes from rhodecode.lib.utils import load_rcextensions - load_rcextensions(root_path=os.path.dirname(rhodecode.CONFIG['__file__'])) + + load_rcextensions(root_path=os.path.dirname(rhodecode.CONFIG["__file__"])) return getattr(rhodecode.EXTENSIONS, self._hook_name, None) return getattr(rhodecode.EXTENSIONS, self._hook_name, None) pre_pull_extension = ExtensionCallback( - hook_name='PRE_PULL_HOOK', + hook_name="PRE_PULL_HOOK", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'hook_type', 'user_agent', 'repo_store_path',)) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "hook_type", + "user_agent", + "repo_store_path", + ), +) post_pull_extension = ExtensionCallback( - hook_name='PULL_HOOK', + hook_name="PULL_HOOK", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'hook_type', 'user_agent', 'repo_store_path',)) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "hook_type", + "user_agent", + "repo_store_path", + ), +) pre_push_extension = ExtensionCallback( - hook_name='PRE_PUSH_HOOK', + hook_name="PRE_PUSH_HOOK", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'repo_store_path', 'commit_ids', 'hook_type', 'user_agent',)) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "repo_store_path", + "commit_ids", + "hook_type", + "user_agent", + ), +) post_push_extension = ExtensionCallback( - hook_name='PUSH_HOOK', + hook_name="PUSH_HOOK", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'repo_store_path', 'commit_ids', 'hook_type', 'user_agent',)) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "repo_store_path", + "commit_ids", + "hook_type", + "user_agent", + ), +) pre_create_user = ExtensionCallback( - hook_name='PRE_CREATE_USER_HOOK', - kwargs_keys=( - 'username', 'password', 'email', 'firstname', 'lastname', 'active', - 'admin', 'created_by')) + hook_name="PRE_CREATE_USER_HOOK", + kwargs_keys=("username", "password", "email", "firstname", "lastname", "active", "admin", "created_by"), +) create_pull_request = ExtensionCallback( - hook_name='CREATE_PULL_REQUEST', + hook_name="CREATE_PULL_REQUEST", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'pull_request_id', 'url', 'title', 'description', - 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status', - 'mergeable', 'source', 'target', 'author', 'reviewers')) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "pull_request_id", + "url", + "title", + "description", + "status", + "created_on", + "updated_on", + "commit_ids", + "review_status", + "mergeable", + "source", + "target", + "author", + "reviewers", + ), +) merge_pull_request = ExtensionCallback( - hook_name='MERGE_PULL_REQUEST', + hook_name="MERGE_PULL_REQUEST", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'pull_request_id', 'url', 'title', 'description', - 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status', - 'mergeable', 'source', 'target', 'author', 'reviewers')) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "pull_request_id", + "url", + "title", + "description", + "status", + "created_on", + "updated_on", + "commit_ids", + "review_status", + "mergeable", + "source", + "target", + "author", + "reviewers", + ), +) close_pull_request = ExtensionCallback( - hook_name='CLOSE_PULL_REQUEST', + hook_name="CLOSE_PULL_REQUEST", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'pull_request_id', 'url', 'title', 'description', - 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status', - 'mergeable', 'source', 'target', 'author', 'reviewers')) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "pull_request_id", + "url", + "title", + "description", + "status", + "created_on", + "updated_on", + "commit_ids", + "review_status", + "mergeable", + "source", + "target", + "author", + "reviewers", + ), +) review_pull_request = ExtensionCallback( - hook_name='REVIEW_PULL_REQUEST', + hook_name="REVIEW_PULL_REQUEST", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'pull_request_id', 'url', 'title', 'description', - 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status', - 'mergeable', 'source', 'target', 'author', 'reviewers')) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "pull_request_id", + "url", + "title", + "description", + "status", + "created_on", + "updated_on", + "commit_ids", + "review_status", + "mergeable", + "source", + "target", + "author", + "reviewers", + ), +) comment_pull_request = ExtensionCallback( - hook_name='COMMENT_PULL_REQUEST', + hook_name="COMMENT_PULL_REQUEST", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'pull_request_id', 'url', 'title', 'description', - 'status', 'comment', 'created_on', 'updated_on', 'commit_ids', 'review_status', - 'mergeable', 'source', 'target', 'author', 'reviewers')) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "pull_request_id", + "url", + "title", + "description", + "status", + "comment", + "created_on", + "updated_on", + "commit_ids", + "review_status", + "mergeable", + "source", + "target", + "author", + "reviewers", + ), +) comment_edit_pull_request = ExtensionCallback( - hook_name='COMMENT_EDIT_PULL_REQUEST', + hook_name="COMMENT_EDIT_PULL_REQUEST", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'pull_request_id', 'url', 'title', 'description', - 'status', 'comment', 'created_on', 'updated_on', 'commit_ids', 'review_status', - 'mergeable', 'source', 'target', 'author', 'reviewers')) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "pull_request_id", + "url", + "title", + "description", + "status", + "comment", + "created_on", + "updated_on", + "commit_ids", + "review_status", + "mergeable", + "source", + "target", + "author", + "reviewers", + ), +) update_pull_request = ExtensionCallback( - hook_name='UPDATE_PULL_REQUEST', + hook_name="UPDATE_PULL_REQUEST", kwargs_keys=( - 'server_url', 'config', 'scm', 'username', 'ip', 'action', - 'repository', 'pull_request_id', 'url', 'title', 'description', - 'status', 'created_on', 'updated_on', 'commit_ids', 'review_status', - 'mergeable', 'source', 'target', 'author', 'reviewers')) + "server_url", + "config", + "scm", + "username", + "ip", + "action", + "repository", + "pull_request_id", + "url", + "title", + "description", + "status", + "created_on", + "updated_on", + "commit_ids", + "review_status", + "mergeable", + "source", + "target", + "author", + "reviewers", + ), +) create_user = ExtensionCallback( - hook_name='CREATE_USER_HOOK', + hook_name="CREATE_USER_HOOK", kwargs_keys=( - 'username', 'full_name_or_username', 'full_contact', 'user_id', - 'name', 'firstname', 'short_contact', 'admin', 'lastname', - 'ip_addresses', 'extern_type', 'extern_name', - 'email', 'api_keys', 'last_login', - 'full_name', 'active', 'password', 'emails', - 'inherit_default_permissions', 'created_by', 'created_on')) + "username", + "full_name_or_username", + "full_contact", + "user_id", + "name", + "firstname", + "short_contact", + "admin", + "lastname", + "ip_addresses", + "extern_type", + "extern_name", + "email", + "api_keys", + "last_login", + "full_name", + "active", + "password", + "emails", + "inherit_default_permissions", + "created_by", + "created_on", + ), +) delete_user = ExtensionCallback( - hook_name='DELETE_USER_HOOK', + hook_name="DELETE_USER_HOOK", kwargs_keys=( - 'username', 'full_name_or_username', 'full_contact', 'user_id', - 'name', 'firstname', 'short_contact', 'admin', 'lastname', - 'ip_addresses', - 'email', 'last_login', - 'full_name', 'active', 'password', 'emails', - 'inherit_default_permissions', 'deleted_by')) + "username", + "full_name_or_username", + "full_contact", + "user_id", + "name", + "firstname", + "short_contact", + "admin", + "lastname", + "ip_addresses", + "email", + "last_login", + "full_name", + "active", + "password", + "emails", + "inherit_default_permissions", + "deleted_by", + ), +) create_repository = ExtensionCallback( - hook_name='CREATE_REPO_HOOK', + hook_name="CREATE_REPO_HOOK", kwargs_keys=( - 'repo_name', 'repo_type', 'description', 'private', 'created_on', - 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics', - 'clone_uri', 'fork_id', 'group_id', 'created_by')) + "repo_name", + "repo_type", + "description", + "private", + "created_on", + "enable_downloads", + "repo_id", + "user_id", + "enable_statistics", + "clone_uri", + "fork_id", + "group_id", + "created_by", + ), +) delete_repository = ExtensionCallback( - hook_name='DELETE_REPO_HOOK', + hook_name="DELETE_REPO_HOOK", kwargs_keys=( - 'repo_name', 'repo_type', 'description', 'private', 'created_on', - 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics', - 'clone_uri', 'fork_id', 'group_id', 'deleted_by', 'deleted_on')) + "repo_name", + "repo_type", + "description", + "private", + "created_on", + "enable_downloads", + "repo_id", + "user_id", + "enable_statistics", + "clone_uri", + "fork_id", + "group_id", + "deleted_by", + "deleted_on", + ), +) comment_commit_repository = ExtensionCallback( - hook_name='COMMENT_COMMIT_REPO_HOOK', + hook_name="COMMENT_COMMIT_REPO_HOOK", kwargs_keys=( - 'repo_name', 'repo_type', 'description', 'private', 'created_on', - 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics', - 'clone_uri', 'fork_id', 'group_id', - 'repository', 'created_by', 'comment', 'commit')) + "repo_name", + "repo_type", + "description", + "private", + "created_on", + "enable_downloads", + "repo_id", + "user_id", + "enable_statistics", + "clone_uri", + "fork_id", + "group_id", + "repository", + "created_by", + "comment", + "commit", + ), +) comment_edit_commit_repository = ExtensionCallback( - hook_name='COMMENT_EDIT_COMMIT_REPO_HOOK', + hook_name="COMMENT_EDIT_COMMIT_REPO_HOOK", kwargs_keys=( - 'repo_name', 'repo_type', 'description', 'private', 'created_on', - 'enable_downloads', 'repo_id', 'user_id', 'enable_statistics', - 'clone_uri', 'fork_id', 'group_id', - 'repository', 'created_by', 'comment', 'commit')) + "repo_name", + "repo_type", + "description", + "private", + "created_on", + "enable_downloads", + "repo_id", + "user_id", + "enable_statistics", + "clone_uri", + "fork_id", + "group_id", + "repository", + "created_by", + "comment", + "commit", + ), +) create_repository_group = ExtensionCallback( - hook_name='CREATE_REPO_GROUP_HOOK', + hook_name="CREATE_REPO_GROUP_HOOK", kwargs_keys=( - 'group_name', 'group_parent_id', 'group_description', - 'group_id', 'user_id', 'created_by', 'created_on', - 'enable_locking')) + "group_name", + "group_parent_id", + "group_description", + "group_id", + "user_id", + "created_by", + "created_on", + "enable_locking", + ), +) diff --git a/rhodecode/lib/hooks_utils.py b/rhodecode/lib/hooks_utils.py index 6f96486e..d23a60f5 100644 --- a/rhodecode/lib/hooks_utils.py +++ b/rhodecode/lib/hooks_utils.py @@ -24,7 +24,7 @@ from rhodecode.lib import utils2 def _supports_repo_type(repo_type): - if repo_type in ('hg', 'git'): + if repo_type in ("hg", "git"): return True return False @@ -34,7 +34,7 @@ def _get_vcs_operation_context(username, repo_name, repo_type, action): from rhodecode.lib.base import vcs_operation_context from rhodecode.lib.pyramid_utils import get_current_request - check_locking = action in ('pull', 'push') + check_locking = action in ("pull", "push") request = get_current_request() @@ -45,7 +45,7 @@ def _get_vcs_operation_context(username, repo_name, repo_type, action): environ = {} if not environ: - environ = webob.Request.blank('').environ + environ = webob.Request.blank("").environ extras = vcs_operation_context(environ, repo_name, username, action, repo_type, check_locking) return utils2.AttributeDict(extras) @@ -81,10 +81,10 @@ def trigger_comment_commit_hooks(username, repo_name, repo_type, repo, data=None if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'comment_commit') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "comment_commit") - comment = data['comment'] - commit = data['commit'] + comment = data["comment"] + commit = data["commit"] events.trigger(events.RepoCommitCommentEvent(repo, commit, comment)) extras.update(repo.get_dict()) @@ -108,10 +108,10 @@ def trigger_comment_commit_edit_hooks(username, repo_name, repo_type, repo, data if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'comment_commit') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "comment_commit") - comment = data['comment'] - commit = data['commit'] + comment = data["comment"] + commit = data["commit"] events.trigger(events.RepoCommitCommentEditEvent(repo, commit, comment)) extras.update(repo.get_dict()) @@ -135,7 +135,7 @@ def trigger_create_pull_request_hook(username, repo_name, repo_type, pull_reques if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'create_pull_request') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "create_pull_request") events.trigger(events.PullRequestCreateEvent(pull_request)) extras.update(pull_request.get_api_data(with_merge_state=False)) hooks_base.create_pull_request(**extras) @@ -154,7 +154,7 @@ def trigger_merge_pull_request_hook(username, repo_name, repo_type, pull_request if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'merge_pull_request') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "merge_pull_request") events.trigger(events.PullRequestMergeEvent(pull_request)) extras.update(pull_request.get_api_data()) hooks_base.merge_pull_request(**extras) @@ -173,7 +173,7 @@ def trigger_close_pull_request_hook(username, repo_name, repo_type, pull_request if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'close_pull_request') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "close_pull_request") events.trigger(events.PullRequestCloseEvent(pull_request)) extras.update(pull_request.get_api_data()) hooks_base.close_pull_request(**extras) @@ -192,8 +192,8 @@ def trigger_review_pull_request_hook(username, repo_name, repo_type, pull_reques if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'review_pull_request') - status = data.get('status') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "review_pull_request") + status = data.get("status") events.trigger(events.PullRequestReviewEvent(pull_request, status)) extras.update(pull_request.get_api_data()) hooks_base.review_pull_request(**extras) @@ -212,9 +212,9 @@ def trigger_comment_pull_request_hook(username, repo_name, repo_type, pull_reque if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'comment_pull_request') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "comment_pull_request") - comment = data['comment'] + comment = data["comment"] events.trigger(events.PullRequestCommentEvent(pull_request, comment)) extras.update(pull_request.get_api_data()) extras.comment = comment.get_api_data() @@ -234,9 +234,9 @@ def trigger_comment_pull_request_edit_hook(username, repo_name, repo_type, pull_ if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'comment_pull_request') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "comment_pull_request") - comment = data['comment'] + comment = data["comment"] events.trigger(events.PullRequestCommentEditEvent(pull_request, comment)) extras.update(pull_request.get_api_data()) extras.comment = comment.get_api_data() @@ -256,7 +256,7 @@ def trigger_update_pull_request_hook(username, repo_name, repo_type, pull_reques if not _supports_repo_type(repo_type): return - extras = _get_vcs_operation_context(username, repo_name, repo_type, 'update_pull_request') + extras = _get_vcs_operation_context(username, repo_name, repo_type, "update_pull_request") events.trigger(events.PullRequestUpdateEvent(pull_request)) extras.update(pull_request.get_api_data()) hooks_base.update_pull_request(**extras) diff --git a/rhodecode/lib/html_filters.py b/rhodecode/lib/html_filters.py index c5eab5c1..d5800d71 100644 --- a/rhodecode/lib/html_filters.py +++ b/rhodecode/lib/html_filters.py @@ -27,6 +27,7 @@ log = logging.getLogger(__name__) # base64 filter e.g ${ example | base64,n } def base64(text): from rhodecode.lib.str_utils import base64_to_str + return base64_to_str(text) @@ -38,25 +39,31 @@ def sanitize_html(text, **kwargs): css_sanitizer = CSSSanitizer(allowed_css_properties=all_styles) - markdown = kwargs.pop('markdown', False) + markdown = kwargs.pop("markdown", False) allowed_attrs = markdown_attrs - cleaner = functools.partial(bleach.clean, - tags=all_tags, - attributes=allowed_attrs, - css_sanitizer=css_sanitizer, - strip_comments=False, **kwargs) + cleaner = functools.partial( + bleach.clean, + tags=all_tags, + attributes=allowed_attrs, + css_sanitizer=css_sanitizer, + strip_comments=False, + **kwargs, + ) if markdown: - cleaner = functools.partial(bleach.clean, - tags=markdown_tags, - attributes=markdown_attrs, - css_sanitizer=css_sanitizer, - strip_comments=False, **kwargs) + cleaner = functools.partial( + bleach.clean, + tags=markdown_tags, + attributes=markdown_attrs, + css_sanitizer=css_sanitizer, + strip_comments=False, + **kwargs, + ) try: return cleaner(text) except Exception: - log.exception('Failed to sanitize html') - return 'TEXT CANNOT BE PARSED USING HTML SANITIZE' + log.exception("Failed to sanitize html") + return "TEXT CANNOT BE PARSED USING HTML SANITIZE" diff --git a/rhodecode/lib/html_sanitizer_defs.py b/rhodecode/lib/html_sanitizer_defs.py index bbe4aaa9..a5b6a1b0 100644 --- a/rhodecode/lib/html_sanitizer_defs.py +++ b/rhodecode/lib/html_sanitizer_defs.py @@ -1,46 +1,172 @@ all_tags = [ - "a", "abbr", "acronym", "address", "applet", "area", "article", "aside", "audio", - "b", "base", "basefont", "bdi", "bdo", "bgsound", "big", "blink", "blockquote", "body", "br", "button", - "canvas", "caption", "center", "cite", "code", "col", "colgroup", "command", "content", - "data", "datalist", "dd", "del", "detals", "dfn", "dialog", "dir", "div", "dl", "dt", - "element", "em", "embed", - "fieldset", "figcaption", "figure", "font", "footer", "form", "frame", "frameset", - "h1", "h2", "h3", "h4", "h5", "h6", "head", "header", "hgroup", "hr", "html", - "i", "iframe", "image", "img", "input", "ins", "isindex", - "kbd", "keygen", - "label", "legend", "li", "link", "listing", - "main", "map", "mark", "marquee", "menu", "menuitem", "meta", "meter", "multicol", - "nav", "nobr", "noembed", "noframes", "noscript", - "object", "ol", "optgroup", "option", "output", - "p", "param", "picture", "plaintext", "pre", "progress", + "a", + "abbr", + "acronym", + "address", + "applet", + "area", + "article", + "aside", + "audio", + "b", + "base", + "basefont", + "bdi", + "bdo", + "bgsound", + "big", + "blink", + "blockquote", + "body", + "br", + "button", + "canvas", + "caption", + "center", + "cite", + "code", + "col", + "colgroup", + "command", + "content", + "data", + "datalist", + "dd", + "del", + "detals", + "dfn", + "dialog", + "dir", + "div", + "dl", + "dt", + "element", + "em", + "embed", + "fieldset", + "figcaption", + "figure", + "font", + "footer", + "form", + "frame", + "frameset", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "head", + "header", + "hgroup", + "hr", + "html", + "i", + "iframe", + "image", + "img", + "input", + "ins", + "isindex", + "kbd", + "keygen", + "label", + "legend", + "li", + "link", + "listing", + "main", + "map", + "mark", + "marquee", + "menu", + "menuitem", + "meta", + "meter", + "multicol", + "nav", + "nobr", + "noembed", + "noframes", + "noscript", + "object", + "ol", + "optgroup", + "option", + "output", + "p", + "param", + "picture", + "plaintext", + "pre", + "progress", "q", - "rp", "rt", "ruby", - "s", "samp", "script", "section", "select", "shadow", "small", "source", "spacer", "span", "strike", "strong", "style", "sub", "summary", "sup", - "table", "tbody", "td", "template", "textarea", "tfoot", "th", "thead", "time", "title", "tr", "track", "tt", - "u", "ul", - "var", "video", + "rp", + "rt", + "ruby", + "s", + "samp", + "script", + "section", + "select", + "shadow", + "small", + "source", + "spacer", + "span", + "strike", + "strong", + "style", + "sub", + "summary", + "sup", + "table", + "tbody", + "td", + "template", + "textarea", + "tfoot", + "th", + "thead", + "time", + "title", + "tr", + "track", + "tt", + "u", + "ul", + "var", + "video", "wbr", "xmp", ] # List tags that, if included in a page, could break markup or open XSS. generally_xss_unsafe = [ - "applet", "audio", - "bgsound", "body", + "applet", + "audio", + "bgsound", + "body", "canvas", "embed", - "frame", "frameset", - "head", "html", + "frame", + "frameset", + "head", + "html", "iframe", "link", "meta", "object", "param", - "source", "script", - "ruby", "rt", - "title", "track", + "source", + "script", + "ruby", + "rt", + "title", + "track", "video", - "xmp" + "xmp", ] # Tags that, if included on the page, will probably not break markup or open @@ -51,19 +177,45 @@ generally_xss_safe.sort() # Tags suitable for rendering markdown markdown_tags = [ - "h1", "h2", "h3", "h4", "h5", "h6", - "b", "i", "strong", "em", "tt", - "p", "br", - "span", "div", "blockquote", "code", "hr", "pre", "del", - "ul", "ol", "li", - "dl", "dd", "dt", - "table", "thead", "tbody", "tfoot", "tr", "th", "td", + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "b", + "i", + "strong", + "em", + "tt", + "p", + "br", + "span", + "div", + "blockquote", + "code", + "hr", + "pre", + "del", + "ul", + "ol", + "li", + "dl", + "dd", + "dt", + "table", + "thead", + "tbody", + "tfoot", + "tr", + "th", + "td", "img", "a", "input", "details", "summary", - "div" + "div", ] markdown_attrs = { @@ -82,328 +234,1029 @@ standard_styles = [ # This includes pseudo-classes, pseudo-elements, @-rules, units, and # selectors in addition to properties, but it doesn't matter for our # purposes -- we don't need to filter styles.. - ":active", "::after (:after)", "align-content", "align-items", "align-self", - "all", "", "animation", "animation-delay", "animation-direction", - "animation-duration", "animation-fill-mode", "animation-iteration-count", - "animation-name", "animation-play-state", "animation-timing-function", - "@annotation", "annotation()", "attr()", "::backdrop", "backface-visibility", - "background", "background-attachment", "background-blend-mode", - "background-clip", "background-color", "background-image", "background-origin", - "background-position", "background-repeat", "background-size", "", - "::before (:before)", "", "blur()", "border", "border-bottom", - "border-bottom-color", "border-bottom-left-radius", - "border-bottom-right-radius", "border-bottom-style", "border-bottom-width", - "border-collapse", "border-color", "border-image", "border-image-outset", - "border-image-repeat", "border-image-slice", "border-image-source", - "border-image-width", "border-left", "border-left-color", "border-left-style", - "border-left-width", "border-radius", "border-right", "border-right-color", - "border-right-style", "border-right-width", "border-spacing", "border-style", - "border-top", "border-top-color", "border-top-left-radius", - "border-top-right-radius", "border-top-style", "border-top-width", - "border-width", "bottom", "box-decoration-break", "box-shadow", "box-sizing", - "break-after", "break-before", "break-inside", "brightness()", "calc()", - "caption-side", "ch", "@character-variant", "character-variant()", "@charset", - ":checked", "circle()", "clear", "clip", "clip-path", "cm", "color", "", - "columns", "column-count", "column-fill", "column-gap", "column-rule", - "column-rule-color", "column-rule-style", "column-rule-width", "column-span", - "column-width", "content", "contrast()", "", "counter-increment", - "counter-reset", "@counter-style", "cubic-bezier()", "cursor", - "", ":default", "deg", ":dir()", "direction", ":disabled", - "display", "@document", "dpcm", "dpi", "dppx", "drop-shadow()", "element()", - "ellipse()", "em", ":empty", "empty-cells", ":enabled", "ex", "filter", - ":first", ":first-child", "::first-letter", "::first-line", - ":first-of-type", "flex", "flex-basis", "flex-direction", - "flex-flow", "flex-grow", "flex-shrink", "flex-wrap", "float", ":focus", - "font", "@font-face", "font-family", "font-feature-settings", - "@font-feature-values", "font-kerning", "font-language-override", "font-size", - "font-size-adjust", "font-stretch", "font-style", "font-synthesis", - "font-variant", "font-variant-alternates", "font-variant-caps", - "font-variant-east-asian", "font-variant-ligatures", "font-variant-numeric", - "font-variant-position", "font-weight", "", ":fullscreen", "grad", - "", "grayscale()", "grid", "grid-area", "grid-auto-columns", - "grid-auto-flow", "grid-auto-position", "grid-auto-rows", "grid-column", - "grid-column-start", "grid-column-end", "grid-row", "grid-row-start", - "grid-row-end", "grid-template", "grid-template-areas", "grid-template-rows", - "grid-template-columns", "height", ":hover", "hsl()", "hsla()", "hue-rotate()", - "hyphens", "hz", "", "image()", "image-rendering", "image-resolution", - "image-orientation", "ime-mode", "@import", "in", ":indeterminate", "inherit", - "initial", ":in-range", "inset()", "", ":invalid", "invert()", - "isolation", "justify-content", "@keyframes", "khz", ":lang()", ":last-child", - ":last-of-type", "left", ":left", "", "letter-spacing", - "linear-gradient()", "line-break", "line-height", ":link", "list-style", - "list-style-image", "list-style-position", "list-style-type", "margin", - "margin-bottom", "margin-left", "margin-right", "margin-top", "marks", "mask", - "mask-type", "matrix()", "matrix3d()", "max-height", "max-width", "@media", - "min-height", "minmax()", "min-width", "mix-blend-mode", "mm", "ms", - "@namespace", ":not()", ":nth-child()", ":nth-last-child()", - ":nth-last-of-type()", ":nth-of-type()", "", "object-fit", - "object-position", ":only-child", ":only-of-type", "opacity", "opacity()", - ":optional", "order", "@ornaments", "ornaments()", "orphans", "outline", - "outline-color", "outline-offset", "outline-style", "outline-width", - ":out-of-range", "overflow", "overflow-wrap", "overflow-x", "overflow-y", - "padding", "padding-bottom", "padding-left", "padding-right", "padding-top", - "@page", "page-break-after", "page-break-before", "page-break-inside", "pc", - "", "perspective", "perspective()", "perspective-origin", - "pointer-events", "polygon()", "position", "", "pt", "px", "quotes", - "rad", "radial-gradient()", "", ":read-only", ":read-write", "rect()", - "rem", "repeat()", "::repeat-index", "::repeat-item", - "repeating-linear-gradient()", "repeating-radial-gradient()", ":required", - "resize", "", "rgb()", "rgba()", "right", ":right", ":root", - "rotate()", "rotatex()", "rotatey()", "rotatez()", "rotate3d()", "ruby-align", - "ruby-merge", "ruby-position", "s", "saturate()", "scale()", "scalex()", - "scaley()", "scalez()", "scale3d()", ":scope", "scroll-behavior", - "::selection", "sepia()", "", "shape-image-threshold", "shape-margin", - "shape-outside", "skew()", "skewx()", "skewy()", "steps()", "", - "@styleset", "styleset()", "@stylistic", "stylistic()", "@supports", "@swash", - "swash()", "symbol()", "table-layout", "tab-size", ":target", "text-align", - "text-align-last", "text-combine-upright", "text-decoration", - "text-decoration-color", "text-decoration-line", "text-decoration-style", - "text-indent", "text-orientation", "text-overflow", "text-rendering", - "text-shadow", "text-transform", "text-underline-position", "extra emails page.').format( - '/_admin/my_account/emails')), + "/_admin/my_account/emails" + ) + ), ) - class AddEmailSchema(colander.Schema): current_password = colander.SchemaNode( colander.String(), missing=colander.required, widget=forms.widget.PasswordWidget(redisplay=True), - validator=deferred_user_password_validator) + validator=deferred_user_password_validator, + ) - email = colander.SchemaNode( - colander.String(), title='New Email', - validator=deferred_additional_email_validator) + email = colander.SchemaNode(colander.String(), title="New Email", validator=deferred_additional_email_validator) diff --git a/rhodecode/model/validation_schema/types.py b/rhodecode/model/validation_schema/types.py index 9b88ef7c..a5b9c04e 100644 --- a/rhodecode/model/validation_schema/types.py +++ b/rhodecode/model/validation_schema/types.py @@ -26,13 +26,13 @@ from rhodecode.model.db import User, UserGroup class _RootLocation(object): pass + RootLocation = _RootLocation() def _normalize(seperator, path): - if not path: - return '' + return "" elif path is colander.null: return colander.null @@ -41,14 +41,14 @@ def _normalize(seperator, path): def bad_parts(value): if not value: return False - if re.match(r'^[.]+$', value): + if re.match(r"^[.]+$", value): return False return True def slugify(value): value = preparers.slugify_preparer(value) - value = re.sub(r'[.]{2,}', '.', value) + value = re.sub(r"[.]{2,}", ".", value) return value clean_parts = [slugify(item) for item in parts if item] @@ -57,7 +57,7 @@ def _normalize(seperator, path): class RepoNameType(colander.String): - SEPARATOR = '/' + SEPARATOR = "/" def deserialize(self, node, cstruct): result = super().deserialize(node, cstruct) @@ -70,7 +70,7 @@ class RepoNameType(colander.String): class GroupNameType(colander.String): - SEPARATOR = '/' + SEPARATOR = "/" def deserialize(self, node, cstruct): if cstruct is RootLocation: @@ -86,16 +86,16 @@ class GroupNameType(colander.String): class StringBooleanType(colander.String): - true_values = ['true', 't', 'yes', 'y', 'on', '1'] - false_values = ['false', 'f', 'no', 'n', 'off', '0'] + true_values = ["true", "t", "yes", "y", "on", "1"] + false_values = ["false", "f", "no", "n", "off", "0"] def serialize(self, node, appstruct): if appstruct is colander.null: return colander.null if not isinstance(appstruct, bool): - raise colander.Invalid(node, '%r is not a boolean' % appstruct) + raise colander.Invalid(node, "%r is not a boolean" % appstruct) - return appstruct and 'true' or 'false' + return appstruct and "true" or "false" def deserialize(self, node, cstruct): if cstruct is colander.null: @@ -105,7 +105,7 @@ class StringBooleanType(colander.String): return cstruct if not isinstance(cstruct, str): - raise colander.Invalid(node, '%r is not a string' % cstruct) + raise colander.Invalid(node, "%r is not a string" % cstruct) value = cstruct.lower() if value in self.true_values: @@ -113,17 +113,17 @@ class StringBooleanType(colander.String): elif value in self.false_values: return False else: - raise colander.Invalid( - node, f'{value} value cannot be translated to bool') + raise colander.Invalid(node, f"{value} value cannot be translated to bool") class UserOrUserGroupType(colander.SchemaType): - """ colander Schema type for valid rhodecode user and/or usergroup """ - scopes = ('user', 'usergroup') + """colander Schema type for valid rhodecode user and/or usergroup""" + + scopes = ("user", "usergroup") def __init__(self): - self.users = 'user' in self.scopes - self.usergroups = 'usergroup' in self.scopes + self.users = "user" in self.scopes + self.usergroups = "usergroup" in self.scopes def serialize(self, node, appstruct): if appstruct is colander.null: @@ -132,17 +132,16 @@ class UserOrUserGroupType(colander.SchemaType): if self.users: if isinstance(appstruct, User): if self.usergroups: - return 'user:%s' % appstruct.username + return "user:%s" % appstruct.username return appstruct.username if self.usergroups: if isinstance(appstruct, UserGroup): if self.users: - return 'usergroup:%s' % appstruct.users_group_name + return "usergroup:%s" % appstruct.users_group_name return appstruct.users_group_name - raise colander.Invalid( - node, '{} is not a valid {}'.format(appstruct, ' or '.join(self.scopes))) + raise colander.Invalid(node, "{} is not a valid {}".format(appstruct, " or ".join(self.scopes))) def deserialize(self, node, cstruct): if cstruct is colander.null: @@ -150,23 +149,28 @@ class UserOrUserGroupType(colander.SchemaType): user, usergroup = None, None if self.users: - if cstruct.startswith('user:'): - user = User.get_by_username(cstruct.split(':')[1]) + if cstruct.startswith("user:"): + user = User.get_by_username(cstruct.split(":")[1]) else: user = User.get_by_username(cstruct) if self.usergroups: - if cstruct.startswith('usergroup:'): - usergroup = UserGroup.get_by_group_name(cstruct.split(':')[1]) + if cstruct.startswith("usergroup:"): + usergroup = UserGroup.get_by_group_name(cstruct.split(":")[1]) else: usergroup = UserGroup.get_by_group_name(cstruct) if self.users and self.usergroups: if user and usergroup: - raise colander.Invalid(node, ( - '%s is both a user and usergroup, specify which ' - 'one was wanted by prepending user: or usergroup: to the ' - 'name') % cstruct) + raise colander.Invalid( + node, + ( + "%s is both a user and usergroup, specify which " + "one was wanted by prepending user: or usergroup: to the " + "name" + ) + % cstruct, + ) if self.users and user: return user @@ -174,16 +178,15 @@ class UserOrUserGroupType(colander.SchemaType): if self.usergroups and usergroup: return usergroup - raise colander.Invalid( - node, '{} is not a valid {}'.format(cstruct, ' or '.join(self.scopes))) + raise colander.Invalid(node, "{} is not a valid {}".format(cstruct, " or ".join(self.scopes))) class UserType(UserOrUserGroupType): - scopes = ('user',) + scopes = ("user",) class UserGroupType(UserOrUserGroupType): - scopes = ('usergroup',) + scopes = ("usergroup",) class StrOrIntType(colander.String): diff --git a/rhodecode/model/validation_schema/utils.py b/rhodecode/model/validation_schema/utils.py index bccb5a31..afec85a1 100644 --- a/rhodecode/model/validation_schema/utils.py +++ b/rhodecode/model/validation_schema/utils.py @@ -24,8 +24,8 @@ def convert_to_optgroup(items): Convert such format:: [ - ['rev:tip', u'latest tip'], - ([(u'branch:default', u'default')], u'Branches'), + ['rev:tip', u'latest tip'], + ([(u'branch:default', u'default')], u'Branches'), ] into one used by deform Select widget:: @@ -48,7 +48,7 @@ def convert_to_optgroup(items): def username_converter(value): - for noise in ('/', ',', '*', '"', "'", '<', '>', '(', ')', '[', ']', ';'): - value = value.replace(noise, '') + for noise in ("/", ",", "*", '"', "'", "<", ">", "(", ")", "[", "]", ";"): + value = value.replace(noise, "") return value diff --git a/rhodecode/model/validation_schema/validators.py b/rhodecode/model/validation_schema/validators.py index d91ca7c9..421775ba 100644 --- a/rhodecode/model/validation_schema/validators.py +++ b/rhodecode/model/validation_schema/validators.py @@ -35,7 +35,7 @@ def ip_addr_validator(node, value): # this raises an ValueError if address is not IpV4 or IpV6 ipaddress.ip_network(safe_str(value), strict=False) except ValueError: - msg = _('Please enter a valid IPv4 or IpV6 address') + msg = _("Please enter a valid IPv4 or IpV6 address") raise colander.Invalid(node, msg) @@ -48,25 +48,26 @@ class IpAddrValidator(object): # this raises an ValueError if address is not IpV4 or IpV6 ipaddress.ip_network(safe_str(value), strict=self.strict) except ValueError: - msg = _('Please enter a valid IPv4 or IpV6 address') + msg = _("Please enter a valid IPv4 or IpV6 address") raise colander.Invalid(node, msg) def glob_validator(node, value): try: - re.compile('^' + glob2re(value) + '$') + re.compile("^" + glob2re(value) + "$") except Exception: - msg = _('Invalid glob pattern') + msg = _("Invalid glob pattern") raise colander.Invalid(node, msg) def valid_name_validator(node, value): from rhodecode.model.validation_schema import types + if value is types.RootLocation: return - msg = _('Name must start with a letter or number. Got `{}`').format(value) - if not re.match(r'^[a-zA-z0-9]{1,}', value): + msg = _("Name must start with a letter or number. Got `{}`").format(value) + if not re.match(r"^[a-zA-z0-9]{1,}", value): raise colander.Invalid(node, msg) @@ -79,46 +80,48 @@ def url_validator(url, repo_type, config): from rhodecode.lib.vcs.backends.git import GitRepository from rhodecode.lib.vcs.backends.svn import SubversionRepository - if repo_type == 'hg': - allowed_prefixes = ('http', 'svn+http', 'git+http') + if repo_type == "hg": + allowed_prefixes = ("http", "svn+http", "git+http") - if 'http' in url[:4]: + if "http" in url[:4]: # initially check if it's at least the proper URL # or does it pass basic auth return MercurialRepository.check_url(url, config) - elif 'svn+http' in url[:8]: # svn->hg import + elif "svn+http" in url[:8]: # svn->hg import SubversionRepository.check_url(url, config) - elif 'git+http' in url[:8]: # git->hg import + elif "git+http" in url[:8]: # git->hg import raise NotImplementedError() else: - exc = InvalidCloneUrl('Clone from URI %s not allowed. ' - 'Allowed url must start with one of %s' - % (url, ','.join(allowed_prefixes))) + exc = InvalidCloneUrl( + "Clone from URI %s not allowed. " + "Allowed url must start with one of %s" % (url, ",".join(allowed_prefixes)) + ) exc.allowed_prefixes = allowed_prefixes raise exc - elif repo_type == 'git': - allowed_prefixes = ('http', 'svn+http', 'hg+http') - if 'http' in url[:4]: + elif repo_type == "git": + allowed_prefixes = ("http", "svn+http", "hg+http") + if "http" in url[:4]: # initially check if it's at least the proper URL # or does it pass basic auth return GitRepository.check_url(url, config) - elif 'svn+http' in url[:8]: # svn->git import + elif "svn+http" in url[:8]: # svn->git import raise NotImplementedError() - elif 'hg+http' in url[:8]: # hg->git import + elif "hg+http" in url[:8]: # hg->git import raise NotImplementedError() else: - exc = InvalidCloneUrl('Clone from URI %s not allowed. ' - 'Allowed url must start with one of %s' - % (url, ','.join(allowed_prefixes))) + exc = InvalidCloneUrl( + "Clone from URI %s not allowed. " + "Allowed url must start with one of %s" % (url, ",".join(allowed_prefixes)) + ) exc.allowed_prefixes = allowed_prefixes raise exc - elif repo_type == 'svn': + elif repo_type == "svn": # no validation for SVN yet return - raise InvalidCloneUrl(f'Invalid repo type specified: `{repo_type}`') + raise InvalidCloneUrl(f"Invalid repo type specified: `{repo_type}`") class CloneUriValidator(object): @@ -126,8 +129,8 @@ class CloneUriValidator(object): self.repo_type = repo_type def __call__(self, node, value): - from rhodecode.lib.utils import make_db_config + try: config = make_db_config(clear_session=False) url_validator(value, self.repo_type, config) @@ -135,11 +138,12 @@ class CloneUriValidator(object): log.warning(e) raise colander.Invalid(node, str(e)) except Exception as e: - log.exception('Url validation failed') + log.exception("Url validation failed") reason = repr(e) - reason = reason.replace('<', '<').replace('>', '>') - msg = _('invalid clone url or credentials for {repo_type} repository. Reason: {reason}')\ - .format(reason=reason, repo_type=self.repo_type) + reason = reason.replace("<", "<").replace(">", ">") + msg = _("invalid clone url or credentials for {repo_type} repository. Reason: {reason}").format( + reason=reason, repo_type=self.repo_type + ) raise colander.Invalid(node, msg) @@ -147,14 +151,13 @@ def json_validator(node, value): try: json.loads(value) except (Exception,): - msg = _('Please enter a valid json object') + msg = _("Please enter a valid json object") raise colander.Invalid(node, msg) def json_validator_with_exc(node, value): - try: json.loads(value) except (Exception,) as e: - msg = _(f'Please enter a valid json object type={type(value)}: `{e}`') + msg = _(f"Please enter a valid json object type={type(value)}: `{e}`") raise colander.Invalid(node, msg) diff --git a/rhodecode/model/validation_schema/widgets.py b/rhodecode/model/validation_schema/widgets.py index 0814ff80..35ffd563 100644 --- a/rhodecode/model/validation_schema/widgets.py +++ b/rhodecode/model/validation_schema/widgets.py @@ -39,8 +39,8 @@ def _normalize_choices(values): class CodeMirrorWidget(deform.widget.TextAreaWidget): - template = 'codemirror' - requirements = (('deform', None), ('codemirror', None)) + template = "codemirror" + requirements = (("deform", None), ("codemirror", None)) class CheckboxChoiceWidgetDesc(deform.widget.CheckboxChoiceWidget): diff --git a/rhodecode/model/validators.py b/rhodecode/model/validators.py index 0d862b1f..97fddabb 100644 --- a/rhodecode/model/validators.py +++ b/rhodecode/model/validators.py @@ -20,7 +20,6 @@ Set of generic validators """ - import os import re import logging @@ -29,15 +28,26 @@ import collections import formencode import ipaddress from formencode.validators import ( - UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, - NotEmpty, IPAddress, CIDR, String, FancyValidator + UnicodeString, + OneOf, + Int, + Number, + Regex, + Email, + Bool, + StringBoolean, + Set, + NotEmpty, + IPAddress, + CIDR, + String, + FancyValidator, ) from sqlalchemy.sql.expression import true from sqlalchemy.util import OrderedSet -from rhodecode.authentication import ( - legacy_plugin_prefix, _import_legacy_plugin) +from rhodecode.authentication import legacy_plugin_prefix, _import_legacy_plugin from rhodecode.authentication.base import loadplugin from rhodecode.apps._base import ADMIN_PREFIX from rhodecode.lib.auth import HasRepoGroupPermissionAny, HasPermissionAny @@ -48,13 +58,26 @@ from rhodecode.lib.hash_utils import md5_safe from rhodecode.lib.vcs.backends.git.repository import GitRepository from rhodecode.lib.vcs.backends.hg.repository import MercurialRepository from rhodecode.lib.vcs.backends.svn.repository import SubversionRepository -from rhodecode.model.db import ( - RepoGroup, Repository, UserGroup, User, ChangesetStatus, Gist) +from rhodecode.model.db import RepoGroup, Repository, UserGroup, User, ChangesetStatus, Gist from rhodecode.model.settings import VcsSettingsModel # silence warnings and pylint -UnicodeString, OneOf, Int, Number, Regex, Email, Bool, StringBoolean, Set, \ - NotEmpty, IPAddress, CIDR, String, FancyValidator +( + UnicodeString, + OneOf, + Int, + Number, + Regex, + Email, + Bool, + StringBoolean, + Set, + NotEmpty, + IPAddress, + CIDR, + String, + FancyValidator, +) log = logging.getLogger(__name__) @@ -76,7 +99,7 @@ def M(self, key, state, **kwargs): :param state: """ - #state._ = staticmethod(_) + # state._ = staticmethod(_) # inject validator into state object return self.message(key, state, **kwargs) @@ -88,15 +111,15 @@ def UniqueList(localizer, convert=None): """ Unique List ! """ + accept_iterator = True messages = { - 'empty': _('Value cannot be an empty list'), - 'missing_value': _('Value cannot be an empty list'), + "empty": _("Value cannot be an empty list"), + "missing_value": _("Value cannot be an empty list"), } def _convert_to_python(self, value, state): - def make_unique(_value): seen = [] return [c for c in _value if not (c in seen or seen.append(c))] @@ -128,8 +151,9 @@ def UniqueListFromString(localizer): class _validator(UniqueList(localizer)): def _convert_to_python(self, value, state): if isinstance(value, str): - value = aslist(value, ',') + value = aslist(value, ",") return super()._convert_to_python(value, state) + return _validator @@ -138,7 +162,7 @@ def ValidSvnPattern(localizer, section, repo_name=None): class _validator(formencode.validators.FancyValidator): messages = { - 'pattern_exists': _('Pattern already exists'), + "pattern_exists": _("Pattern already exists"), } def _validate_python(self, value, state): @@ -148,8 +172,9 @@ def ValidSvnPattern(localizer, section, repo_name=None): ui_settings = model.get_svn_patterns(section=section) for entry in ui_settings: if value == entry.value: - msg = M(self, 'pattern_exists', state) + msg = M(self, "pattern_exists", state) raise formencode.Invalid(msg, value, state) + return _validator @@ -159,33 +184,33 @@ def ValidUsername(localizer, edit=False, old_data=None): class _validator(formencode.validators.FancyValidator): messages = { - 'username_exists': _('Username "%(username)s" already exists'), - 'system_invalid_username': - _('Username "%(username)s" is forbidden'), - 'invalid_username': - _('Username may only contain alphanumeric characters ' - 'underscores, periods or dashes and must begin with ' - 'alphanumeric character or underscore') + "username_exists": _('Username "%(username)s" already exists'), + "system_invalid_username": _('Username "%(username)s" is forbidden'), + "invalid_username": _( + "Username may only contain alphanumeric characters " + "underscores, periods or dashes and must begin with " + "alphanumeric character or underscore" + ), } def _validate_python(self, value, state): - if value in ['default', 'new_user']: - msg = M(self, 'system_invalid_username', state, username=value) + if value in ["default", "new_user"]: + msg = M(self, "system_invalid_username", state, username=value) raise formencode.Invalid(msg, value, state) # check if user is unique old_un = None if edit: - old_un = User.get(old_data.get('user_id')).username + old_un = User.get(old_data.get("user_id")).username if old_un != value or not edit: if User.get_by_username(value, case_insensitive=True): - msg = M(self, 'username_exists', state, username=value) + msg = M(self, "username_exists", state, username=value) raise formencode.Invalid(msg, value, state) - if (re.match(r'^[\w]{1}[\w\-\.]{0,254}$', value) - is None): - msg = M(self, 'invalid_username', state) + if re.match(r"^[\w]{1}[\w\-\.]{0,254}$", value) is None: + msg = M(self, "invalid_username", state) raise formencode.Invalid(msg, value, state) + return _validator @@ -194,23 +219,20 @@ def ValidRepoUser(localizer, allow_disabled=False): class _validator(formencode.validators.FancyValidator): messages = { - 'invalid_username': _('Username %(username)s is not valid'), - 'disabled_username': _('Username %(username)s is disabled') + "invalid_username": _("Username %(username)s is not valid"), + "disabled_username": _("Username %(username)s is disabled"), } def _validate_python(self, value, state): try: user = User.query().filter(User.username == value).one() except Exception: - msg = M(self, 'invalid_username', state, username=value) - raise formencode.Invalid( - msg, value, state, error_dict={'username': msg} - ) + msg = M(self, "invalid_username", state, username=value) + raise formencode.Invalid(msg, value, state, error_dict={"username": msg}) if user and (not allow_disabled and not user.active): - msg = M(self, 'disabled_username', state, username=value) - raise formencode.Invalid( - msg, value, state, error_dict={'username': msg} - ) + msg = M(self, "disabled_username", state, username=value) + raise formencode.Invalid(msg, value, state, error_dict={"username": msg}) + return _validator @@ -220,36 +242,35 @@ def ValidUserGroup(localizer, edit=False, old_data=None): class _validator(formencode.validators.FancyValidator): messages = { - 'invalid_group': _('Invalid user group name'), - 'group_exist': _('User group `%(usergroup)s` already exists'), - 'invalid_usergroup_name': - _('User group name may only contain alphanumeric ' - 'characters underscores, periods or dashes and must begin ' - 'with alphanumeric character') + "invalid_group": _("Invalid user group name"), + "group_exist": _("User group `%(usergroup)s` already exists"), + "invalid_usergroup_name": _( + "User group name may only contain alphanumeric " + "characters underscores, periods or dashes and must begin " + "with alphanumeric character" + ), } def _validate_python(self, value, state): - if value in ['default']: - msg = M(self, 'invalid_group', state) + if value in ["default"]: + msg = M(self, "invalid_group", state) raise formencode.Invalid(msg, value, state) # check if group is unique old_ugname = None if edit: - old_id = old_data.get('users_group_id') + old_id = old_data.get("users_group_id") old_ugname = UserGroup.get(old_id).users_group_name if old_ugname != value or not edit: - is_existing_group = UserGroup.get_by_group_name( - value, case_insensitive=True) + is_existing_group = UserGroup.get_by_group_name(value, case_insensitive=True) if is_existing_group: - msg = M(self, 'group_exist', state, usergroup=value) - raise formencode.Invalid( - msg, value, state, error_dict={'users_group_name': msg} - ) + msg = M(self, "group_exist", state, usergroup=value) + raise formencode.Invalid(msg, value, state, error_dict={"users_group_name": msg}) - if re.match(r'^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$', value) is None: - msg = M(self, 'invalid_usergroup_name', state) + if re.match(r"^[a-zA-Z0-9]{1}[a-zA-Z0-9\-\_\.]+$", value) is None: + msg = M(self, "invalid_usergroup_name", state) raise formencode.Invalid(msg, value, state) + return _validator @@ -259,46 +280,40 @@ def ValidRepoGroup(localizer, edit=False, old_data=None, can_create_in_root=Fals class _validator(formencode.validators.FancyValidator): messages = { - 'group_parent_id': _('Cannot assign this group as parent'), - 'group_exists': _('Group "%(group_name)s" already exists'), - 'repo_exists': _('Repository with name "%(group_name)s" ' - 'already exists'), - 'permission_denied': _("no permission to store repository group" - "in this location"), - 'permission_denied_root': _( - "no permission to store repository group " - "in root location") + "group_parent_id": _("Cannot assign this group as parent"), + "group_exists": _('Group "%(group_name)s" already exists'), + "repo_exists": _('Repository with name "%(group_name)s" already exists'), + "permission_denied": _("no permission to store repository groupin this location"), + "permission_denied_root": _("no permission to store repository group in root location"), } def _convert_to_python(self, value, state): - group_name = repo_name_slug(value.get('group_name', '')) - group_parent_id = safe_int(value.get('group_parent_id')) + group_name = repo_name_slug(value.get("group_name", "")) + group_parent_id = safe_int(value.get("group_parent_id")) gr = RepoGroup.get(group_parent_id) if gr: parent_group_path = gr.full_path # value needs to be aware of group name in order to check # db key This is an actual just the name to store in the # database - group_name_full = ( - parent_group_path + RepoGroup.url_sep() + group_name) + group_name_full = parent_group_path + RepoGroup.url_sep() + group_name else: group_name_full = group_name - value['group_name'] = group_name - value['group_name_full'] = group_name_full - value['group_parent_id'] = group_parent_id + value["group_name"] = group_name + value["group_name_full"] = group_name_full + value["group_parent_id"] = group_parent_id return value def _validate_python(self, value, state): - old_group_name = None - group_name = value.get('group_name') - group_name_full = value.get('group_name_full') - group_parent_id = safe_int(value.get('group_parent_id')) + group_name = value.get("group_name") + group_name_full = value.get("group_name_full") + group_parent_id = safe_int(value.get("group_parent_id")) if group_parent_id == -1: group_parent_id = None - group_obj = RepoGroup.get(old_data.get('group_id')) + group_obj = RepoGroup.get(old_data.get("group_id")) parent_group_changed = False if edit: old_group_name = group_obj.group_name @@ -312,50 +327,38 @@ def ValidRepoGroup(localizer, edit=False, old_data=None, can_create_in_root=Fals # Can be removed. # check against setting a parent of self - parent_of_self = ( - old_data['group_id'] == group_parent_id - if group_parent_id else False - ) + parent_of_self = old_data["group_id"] == group_parent_id if group_parent_id else False if parent_of_self: - msg = M(self, 'group_parent_id', state) - raise formencode.Invalid( - msg, value, state, error_dict={'group_parent_id': msg} - ) + msg = M(self, "group_parent_id", state) + raise formencode.Invalid(msg, value, state, error_dict={"group_parent_id": msg}) # group we're moving current group inside child_group = None if group_parent_id: - child_group = RepoGroup.query().filter( - RepoGroup.group_id == group_parent_id).scalar() + child_group = RepoGroup.query().filter(RepoGroup.group_id == group_parent_id).scalar() # do a special check that we cannot move a group to one of # it's children if edit and child_group: parents = [x.group_id for x in child_group.parents] - move_to_children = old_data['group_id'] in parents + move_to_children = old_data["group_id"] in parents if move_to_children: - msg = M(self, 'group_parent_id', state) - raise formencode.Invalid( - msg, value, state, error_dict={'group_parent_id': msg}) + msg = M(self, "group_parent_id", state) + raise formencode.Invalid(msg, value, state, error_dict={"group_parent_id": msg}) # Check if we have permission to store in the parent. # Only check if the parent group changed. if parent_group_changed: if child_group is None: if not can_create_in_root: - msg = M(self, 'permission_denied_root', state) - raise formencode.Invalid( - msg, value, state, - error_dict={'group_parent_id': msg}) + msg = M(self, "permission_denied_root", state) + raise formencode.Invalid(msg, value, state, error_dict={"group_parent_id": msg}) else: - valid = HasRepoGroupPermissionAny('group.admin') - forbidden = not valid( - child_group.group_name, 'can create group validator') + valid = HasRepoGroupPermissionAny("group.admin") + forbidden = not valid(child_group.group_name, "can create group validator") if forbidden: - msg = M(self, 'permission_denied', state) - raise formencode.Invalid( - msg, value, state, - error_dict={'group_parent_id': msg}) + msg = M(self, "permission_denied", state) + raise formencode.Invalid(msg, value, state, error_dict={"group_parent_id": msg}) # if we change the name or it's new group, check for existing names # or repositories with the same name @@ -363,16 +366,15 @@ def ValidRepoGroup(localizer, edit=False, old_data=None, can_create_in_root=Fals # check group gr = RepoGroup.get_by_group_name(group_name_full) if gr: - msg = M(self, 'group_exists', state, group_name=group_name) - raise formencode.Invalid( - msg, value, state, error_dict={'group_name': msg}) + msg = M(self, "group_exists", state, group_name=group_name) + raise formencode.Invalid(msg, value, state, error_dict={"group_name": msg}) # check for same repo repo = Repository.get_by_repo_name(group_name_full) if repo: - msg = M(self, 'repo_exists', state, group_name=group_name) - raise formencode.Invalid( - msg, value, state, error_dict={'group_name': msg}) + msg = M(self, "repo_exists", state, group_name=group_name) + raise formencode.Invalid(msg, value, state, error_dict={"group_name": msg}) + return _validator @@ -380,37 +382,34 @@ def ValidPassword(localizer): _ = localizer class _validator(formencode.validators.FancyValidator): - messages = { - 'invalid_password': - _('Invalid characters (non-ascii) in password') - } + messages = {"invalid_password": _("Invalid characters (non-ascii) in password")} def _validate_python(self, value, state): if value and not value.isascii(): - msg = M(self, 'invalid_password', state) - raise formencode.Invalid(msg, value, state,) + msg = M(self, "invalid_password", state) + raise formencode.Invalid( + msg, + value, + state, + ) + return _validator -def ValidPasswordsMatch( - localizer, passwd='new_password', - passwd_confirmation='password_confirmation'): +def ValidPasswordsMatch(localizer, passwd="new_password", passwd_confirmation="password_confirmation"): _ = localizer class _validator(formencode.validators.FancyValidator): messages = { - 'password_mismatch': _('Passwords do not match'), + "password_mismatch": _("Passwords do not match"), } def _validate_python(self, value, state): - - pass_val = value.get('password') or value.get(passwd) + pass_val = value.get("password") or value.get(passwd) if pass_val != value[passwd_confirmation]: - msg = M(self, 'password_mismatch', state) - raise formencode.Invalid( - msg, value, state, - error_dict={passwd: msg, passwd_confirmation: msg} - ) + msg = M(self, "password_mismatch", state) + raise formencode.Invalid(msg, value, state, error_dict={passwd: msg, passwd_confirmation: msg}) + return _validator @@ -419,34 +418,29 @@ def ValidAuth(localizer): class _validator(formencode.validators.FancyValidator): messages = { - 'invalid_password': _('invalid password'), - 'invalid_username': _('invalid user name'), - 'disabled_account': _('Your account is disabled') + "invalid_password": _("invalid password"), + "invalid_username": _("invalid user name"), + "disabled_account": _("Your account is disabled"), } def _validate_python(self, value, state): from rhodecode.authentication.base import authenticate, HTTP_TYPE - password = value['password'] - username = value['username'] + password = value["password"] + username = value["username"] - if not authenticate(username, password, '', HTTP_TYPE, - skip_missing=True): + if not authenticate(username, password, "", HTTP_TYPE, skip_missing=True): user = User.get_by_username_or_primary_email(username) if user and not user.active: - log.warning('user %s is disabled', username) - msg = M(self, 'disabled_account', state) - raise formencode.Invalid( - msg, value, state, error_dict={'username': msg} - ) + log.warning("user %s is disabled", username) + msg = M(self, "disabled_account", state) + raise formencode.Invalid(msg, value, state, error_dict={"username": msg}) else: - log.warning('user `%s` failed to authenticate', username) - msg = M(self, 'invalid_username', state) - msg2 = M(self, 'invalid_password', state) - raise formencode.Invalid( - msg, value, state, - error_dict={'username': msg, 'password': msg2} - ) + log.warning("user `%s` failed to authenticate", username) + msg = M(self, "invalid_username", state) + msg2 = M(self, "invalid_password", state) + raise formencode.Invalid(msg, value, state, error_dict={"username": msg, "password": msg2}) + return _validator @@ -456,24 +450,18 @@ def ValidRepoName(localizer, edit=False, old_data=None): class _validator(formencode.validators.FancyValidator): messages = { - 'invalid_repo_name': - _('Repository name %(repo)s is disallowed'), + "invalid_repo_name": _("Repository name %(repo)s is disallowed"), # top level - 'repository_exists': _('Repository with name %(repo)s ' - 'already exists'), - 'group_exists': _('Repository group with name "%(repo)s" ' - 'already exists'), + "repository_exists": _("Repository with name %(repo)s already exists"), + "group_exists": _('Repository group with name "%(repo)s" already exists'), # inside a group - 'repository_in_group_exists': _('Repository with name %(repo)s ' - 'exists in group "%(group)s"'), - 'group_in_group_exists': _( - 'Repository group with name "%(repo)s" ' - 'exists in group "%(group)s"'), + "repository_in_group_exists": _('Repository with name %(repo)s exists in group "%(group)s"'), + "group_in_group_exists": _('Repository group with name "%(repo)s" exists in group "%(group)s"'), } def _convert_to_python(self, value, state): - repo_name = repo_name_slug(value.get('repo_name', '')) - repo_group = value.get('repo_group') + repo_name = repo_name_slug(value.get("repo_name", "")) + repo_group = value.get("repo_group") if repo_group: gr = RepoGroup.get(repo_group) group_path = gr.full_path @@ -483,54 +471,45 @@ def ValidRepoName(localizer, edit=False, old_data=None): # database repo_name_full = group_path + RepoGroup.url_sep() + repo_name else: - group_name = group_path = '' + group_name = group_path = "" repo_name_full = repo_name - value['repo_name'] = repo_name - value['repo_name_full'] = repo_name_full - value['group_path'] = group_path - value['group_name'] = group_name + value["repo_name"] = repo_name + value["repo_name_full"] = repo_name_full + value["group_path"] = group_path + value["group_name"] = group_name return value def _validate_python(self, value, state): + repo_name = value.get("repo_name") + repo_name_full = value.get("repo_name_full") + group_path = value.get("group_path") + group_name = value.get("group_name") - repo_name = value.get('repo_name') - repo_name_full = value.get('repo_name_full') - group_path = value.get('group_path') - group_name = value.get('group_name') + if repo_name in [ADMIN_PREFIX, ""]: + msg = M(self, "invalid_repo_name", state, repo=repo_name) + raise formencode.Invalid(msg, value, state, error_dict={"repo_name": msg}) - if repo_name in [ADMIN_PREFIX, '']: - msg = M(self, 'invalid_repo_name', state, repo=repo_name) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_name': msg}) - - rename = old_data.get('repo_name') != repo_name_full + rename = old_data.get("repo_name") != repo_name_full create = not edit if rename or create: - if group_path: if Repository.get_by_repo_name(repo_name_full): - msg = M(self, 'repository_in_group_exists', state, - repo=repo_name, group=group_name) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_name': msg}) + msg = M(self, "repository_in_group_exists", state, repo=repo_name, group=group_name) + raise formencode.Invalid(msg, value, state, error_dict={"repo_name": msg}) if RepoGroup.get_by_group_name(repo_name_full): - msg = M(self, 'group_in_group_exists', state, - repo=repo_name, group=group_name) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_name': msg}) + msg = M(self, "group_in_group_exists", state, repo=repo_name, group=group_name) + raise formencode.Invalid(msg, value, state, error_dict={"repo_name": msg}) else: if RepoGroup.get_by_group_name(repo_name_full): - msg = M(self, 'group_exists', state, repo=repo_name) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_name': msg}) + msg = M(self, "group_exists", state, repo=repo_name) + raise formencode.Invalid(msg, value, state, error_dict={"repo_name": msg}) if Repository.get_by_repo_name(repo_name_full): - msg = M( - self, 'repository_exists', state, repo=repo_name) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_name': msg}) + msg = M(self, "repository_exists", state, repo=repo_name) + raise formencode.Invalid(msg, value, state, error_dict={"repo_name": msg}) return value + return _validator @@ -542,107 +521,107 @@ def ValidForkName(localizer, *args, **kwargs): def SlugifyName(localizer): _ = localizer - - class _validator(formencode.validators.FancyValidator): + class _validator(formencode.validators.FancyValidator): def _convert_to_python(self, value, state): return repo_name_slug(value) def _validate_python(self, value, state): pass + return _validator def CannotHaveGitSuffix(localizer): _ = localizer - + class _validator(formencode.validators.FancyValidator): messages = { - 'has_git_suffix': - _('Repository name cannot end with .git'), + "has_git_suffix": _("Repository name cannot end with .git"), } def _convert_to_python(self, value, state): return value def _validate_python(self, value, state): - if value and value.endswith('.git'): - msg = M( - self, 'has_git_suffix', state) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_name': msg}) + if value and value.endswith(".git"): + msg = M(self, "has_git_suffix", state) + raise formencode.Invalid(msg, value, state, error_dict={"repo_name": msg}) + return _validator def ValidCloneUri(localizer): _ = localizer - + class InvalidCloneUrl(Exception): allowed_prefixes = () def url_handler(repo_type, url): config = make_db_config(clear_session=False) - if repo_type == 'hg': - allowed_prefixes = ('http', 'svn+http', 'git+http') + if repo_type == "hg": + allowed_prefixes = ("http", "svn+http", "git+http") - if 'http' in url[:4]: + if "http" in url[:4]: # initially check if it's at least the proper URL # or does it pass basic auth MercurialRepository.check_url(url, config) - elif 'svn+http' in url[:8]: # svn->hg import + elif "svn+http" in url[:8]: # svn->hg import SubversionRepository.check_url(url, config) - elif 'git+http' in url[:8]: # git->hg import + elif "git+http" in url[:8]: # git->hg import raise NotImplementedError() else: - exc = InvalidCloneUrl('Clone from URI %s not allowed. ' - 'Allowed url must start with one of %s' - % (url, ','.join(allowed_prefixes))) + exc = InvalidCloneUrl( + "Clone from URI %s not allowed. " + "Allowed url must start with one of %s" % (url, ",".join(allowed_prefixes)) + ) exc.allowed_prefixes = allowed_prefixes raise exc - elif repo_type == 'git': - allowed_prefixes = ('http', 'svn+http', 'hg+http') - if 'http' in url[:4]: + elif repo_type == "git": + allowed_prefixes = ("http", "svn+http", "hg+http") + if "http" in url[:4]: # initially check if it's at least the proper URL # or does it pass basic auth GitRepository.check_url(url, config) - elif 'svn+http' in url[:8]: # svn->git import + elif "svn+http" in url[:8]: # svn->git import raise NotImplementedError() - elif 'hg+http' in url[:8]: # hg->git import + elif "hg+http" in url[:8]: # hg->git import raise NotImplementedError() else: - exc = InvalidCloneUrl('Clone from URI %s not allowed. ' - 'Allowed url must start with one of %s' - % (url, ','.join(allowed_prefixes))) + exc = InvalidCloneUrl( + "Clone from URI %s not allowed. " + "Allowed url must start with one of %s" % (url, ",".join(allowed_prefixes)) + ) exc.allowed_prefixes = allowed_prefixes raise exc class _validator(formencode.validators.FancyValidator): messages = { - 'clone_uri': _('invalid clone url or credentials for %(rtype)s repository'), - 'invalid_clone_uri': _( - 'Invalid clone url, provide a valid clone ' - 'url starting with one of %(allowed_prefixes)s') + "clone_uri": _("invalid clone url or credentials for %(rtype)s repository"), + "invalid_clone_uri": _( + "Invalid clone url, provide a valid clone url starting with one of %(allowed_prefixes)s" + ), } def _validate_python(self, value, state): - repo_type = value.get('repo_type') - url = value.get('clone_uri') + repo_type = value.get("repo_type") + url = value.get("clone_uri") if url: try: url_handler(repo_type, url) except InvalidCloneUrl as e: log.warning(e) - msg = M(self, 'invalid_clone_uri', state, rtype=repo_type, - allowed_prefixes=','.join(e.allowed_prefixes)) - raise formencode.Invalid(msg, value, state, - error_dict={'clone_uri': msg}) + msg = M( + self, "invalid_clone_uri", state, rtype=repo_type, allowed_prefixes=",".join(e.allowed_prefixes) + ) + raise formencode.Invalid(msg, value, state, error_dict={"clone_uri": msg}) except Exception: - log.exception('Url validation failed') - msg = M(self, 'clone_uri', state, rtype=repo_type) - raise formencode.Invalid(msg, value, state, - error_dict={'clone_uri': msg}) + log.exception("Url validation failed") + msg = M(self, "clone_uri", state, rtype=repo_type) + raise formencode.Invalid(msg, value, state, error_dict={"clone_uri": msg}) + return _validator @@ -651,16 +630,13 @@ def ValidForkType(localizer, old_data=None): old_data = old_data or {} class _validator(formencode.validators.FancyValidator): - messages = { - 'invalid_fork_type': _('Fork have to be the same type as parent') - } + messages = {"invalid_fork_type": _("Fork have to be the same type as parent")} def _validate_python(self, value, state): - if old_data['repo_type'] != value: - msg = M(self, 'invalid_fork_type', state) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_type': msg} - ) + if old_data["repo_type"] != value: + msg = M(self, "invalid_fork_type", state) + raise formencode.Invalid(msg, value, state, error_dict={"repo_type": msg}) + return _validator @@ -669,12 +645,8 @@ def CanWriteGroup(localizer, old_data=None): class _validator(formencode.validators.FancyValidator): messages = { - 'permission_denied': _( - "You do not have the permission " - "to create repositories in this group."), - 'permission_denied_root': _( - "You do not have the permission to store repositories in " - "the root location.") + "permission_denied": _("You do not have the permission to create repositories in this group."), + "permission_denied_root": _("You do not have the permission to store repositories in the root location."), } def _convert_to_python(self, value, state): @@ -687,17 +659,12 @@ def CanWriteGroup(localizer, old_data=None): gr = RepoGroup.get(value) gr_name = gr.group_name if gr else None # None means ROOT location # create repositories with write permission on group is set to true - create_on_write = HasPermissionAny( - 'hg.create.write_on_repogroup.true')() - group_admin = HasRepoGroupPermissionAny('group.admin')( - gr_name, 'can write into group validator') - group_write = HasRepoGroupPermissionAny('group.write')( - gr_name, 'can write into group validator') + create_on_write = HasPermissionAny("hg.create.write_on_repogroup.true")() + group_admin = HasRepoGroupPermissionAny("group.admin")(gr_name, "can write into group validator") + group_write = HasRepoGroupPermissionAny("group.write")(gr_name, "can write into group validator") forbidden = not (group_admin or (group_write and create_on_write)) - can_create_repos = HasPermissionAny( - 'hg.admin', 'hg.create.repository') - gid = (old_data['repo_group'].get('group_id') - if (old_data and 'repo_group' in old_data) else None) + can_create_repos = HasPermissionAny("hg.admin", "hg.create.repository") + gid = old_data["repo_group"].get("group_id") if (old_data and "repo_group" in old_data) else None value_changed = gid != safe_int(value) new = not old_data # do check if we changed the value, there's a case that someone got @@ -707,33 +674,27 @@ def CanWriteGroup(localizer, old_data=None): if value_changed or new: # parent group need to be existing if gr and forbidden: - msg = M(self, 'permission_denied', state) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_type': msg} - ) + msg = M(self, "permission_denied", state) + raise formencode.Invalid(msg, value, state, error_dict={"repo_type": msg}) # check if we can write to root location ! elif gr is None and not can_create_repos(): - msg = M(self, 'permission_denied_root', state) - raise formencode.Invalid( - msg, value, state, error_dict={'repo_type': msg} - ) + msg = M(self, "permission_denied_root", state) + raise formencode.Invalid(msg, value, state, error_dict={"repo_type": msg}) + return _validator -def ValidPerms(localizer, type_='repo'): +def ValidPerms(localizer, type_="repo"): _ = localizer - if type_ == 'repo_group': - EMPTY_PERM = 'group.none' - elif type_ == 'repo': - EMPTY_PERM = 'repository.none' - elif type_ == 'user_group': - EMPTY_PERM = 'usergroup.none' + if type_ == "repo_group": + EMPTY_PERM = "group.none" + elif type_ == "repo": + EMPTY_PERM = "repository.none" + elif type_ == "user_group": + EMPTY_PERM = "usergroup.none" class _validator(formencode.validators.FancyValidator): - messages = { - 'perm_new_member_name': - _('This username or user group name is not valid') - } + messages = {"perm_new_member_name": _("This username or user group name is not valid")} def _convert_to_python(self, value, state): perm_updates = OrderedSet() @@ -746,21 +707,21 @@ def ValidPerms(localizer, type_='repo'): new_perms_group = collections.defaultdict(dict) del_perms_group = collections.defaultdict(dict) for k, v in list(value.copy().items()): - if k.startswith('perm_del_member'): + if k.startswith("perm_del_member"): # delete from org storage so we don't process that later del value[k] # part is `id`, `type` - _type, part = k.split('perm_del_member_') - args = part.split('_') + _type, part = k.split("perm_del_member_") + args = part.split("_") if len(args) == 2: _key, pos = args del_perms_group[pos][_key] = v - if k.startswith('perm_new_member'): + if k.startswith("perm_new_member"): # delete from org storage so we don't process that later del value[k] # part is `id`, `type`, `perm` - _type, part = k.split('perm_new_member_') - args = part.split('_') + _type, part = k.split("perm_new_member_") + args = part.split("_") if len(args) == 2: _key, pos = args new_perms_group[pos][_key] = v @@ -768,75 +729,65 @@ def ValidPerms(localizer, type_='repo'): # store the deletes for k in sorted(del_perms_group.keys()): perm_dict = del_perms_group[k] - del_member = perm_dict.get('id') - del_type = perm_dict.get('type') + del_member = perm_dict.get("id") + del_type = perm_dict.get("type") if del_member and del_type: - perm_deletions.add( - (del_member, None, del_type)) + perm_deletions.add((del_member, None, del_type)) # store additions in order of how they were added in web form for k in sorted(new_perms_group.keys()): perm_dict = new_perms_group[k] - new_member = perm_dict.get('id') - new_type = perm_dict.get('type') - new_perm = perm_dict.get('perm') + new_member = perm_dict.get("id") + new_type = perm_dict.get("type") + new_perm = perm_dict.get("perm") if new_member and new_perm and new_type: - perm_additions.add( - (new_member, new_perm, new_type)) + perm_additions.add((new_member, new_perm, new_type)) # get updates of permissions # (read the existing radio button states) default_user_id = User.get_default_user_id() for k, update_value in list(value.items()): - if k.startswith('u_perm_') or k.startswith('g_perm_'): + if k.startswith("u_perm_") or k.startswith("g_perm_"): obj_type = k[0] obj_id = k[7:] - update_type = {'u': 'user', - 'g': 'user_group'}[obj_type] + update_type = {"u": "user", "g": "user_group"}[obj_type] - if obj_type == 'u' and safe_int(obj_id) == default_user_id: - if str2bool(value.get('repo_private')): + if obj_type == "u" and safe_int(obj_id) == default_user_id: + if str2bool(value.get("repo_private")): # prevent from updating default user permissions # when this repository is marked as private update_value = EMPTY_PERM - perm_updates.add( - (obj_id, update_value, update_type)) + perm_updates.add((obj_id, update_value, update_type)) - value['perm_additions'] = [] # propagated later - value['perm_updates'] = list(perm_updates) - value['perm_deletions'] = list(perm_deletions) + value["perm_additions"] = [] # propagated later + value["perm_updates"] = list(perm_updates) + value["perm_deletions"] = list(perm_deletions) - updates_map = dict( - (x[0], (x[1], x[2])) for x in value['perm_updates']) + updates_map = dict((x[0], (x[1], x[2])) for x in value["perm_updates"]) # make sure Additions don't override updates. for member_id, perm, member_type in list(perm_additions): if member_id in updates_map: perm = updates_map[member_id][0] - value['perm_additions'].append((member_id, perm, member_type)) + value["perm_additions"].append((member_id, perm, member_type)) # on new entries validate users they exist and they are active ! # this leaves feedback to the form try: - if member_type == 'user': - User.query()\ - .filter(User.active == true())\ - .filter(User.user_id == member_id).one() - if member_type == 'user_group': - UserGroup.query()\ - .filter(UserGroup.users_group_active == true())\ - .filter(UserGroup.users_group_id == member_id)\ - .one() + if member_type == "user": + User.query().filter(User.active == true()).filter(User.user_id == member_id).one() + if member_type == "user_group": + UserGroup.query().filter(UserGroup.users_group_active == true()).filter( + UserGroup.users_group_id == member_id + ).one() except Exception: - log.exception('Updated permission failed: org_exc:') - msg = M(self, 'perm_new_member_type', state) - raise formencode.Invalid( - msg, value, state, error_dict={ - 'perm_new_member_name': msg} - ) + log.exception("Updated permission failed: org_exc:") + msg = M(self, "perm_new_member_type", state) + raise formencode.Invalid(msg, value, state, error_dict={"perm_new_member_name": msg}) return value + return _validator @@ -844,16 +795,13 @@ def ValidPath(localizer): _ = localizer class _validator(formencode.validators.FancyValidator): - messages = { - 'invalid_path': _('This is not a valid path') - } + messages = {"invalid_path": _("This is not a valid path")} def _validate_python(self, value, state): if not os.path.isdir(value): - msg = M(self, 'invalid_path', state) - raise formencode.Invalid( - msg, value, state, error_dict={'paths_root_path': msg} - ) + msg = M(self, "invalid_path", state) + raise formencode.Invalid(msg, value, state, error_dict={"paths_root_path": msg}) + return _validator @@ -862,21 +810,18 @@ def UniqSystemEmail(localizer, old_data=None): old_data = old_data or {} class _validator(formencode.validators.FancyValidator): - messages = { - 'email_taken': _('This e-mail address is already taken') - } + messages = {"email_taken": _("This e-mail address is already taken")} def _convert_to_python(self, value, state): return value.lower() def _validate_python(self, value, state): - if (old_data.get('email') or '').lower() != value: + if (old_data.get("email") or "").lower() != value: user = User.get_by_email(value, case_insensitive=True) if user: - msg = M(self, 'email_taken', state) - raise formencode.Invalid( - msg, value, state, error_dict={'email': msg} - ) + msg = M(self, "email_taken", state) + raise formencode.Invalid(msg, value, state, error_dict={"email": msg}) + return _validator @@ -884,9 +829,7 @@ def ValidSystemEmail(localizer): _ = localizer class _validator(formencode.validators.FancyValidator): - messages = { - 'non_existing_email': _('e-mail "%(email)s" does not exist.') - } + messages = {"non_existing_email": _('e-mail "%(email)s" does not exist.')} def _convert_to_python(self, value, state): return value.lower() @@ -894,42 +837,41 @@ def ValidSystemEmail(localizer): def _validate_python(self, value, state): user = User.get_by_email(value, case_insensitive=True) if user is None: - msg = M(self, 'non_existing_email', state, email=value) - raise formencode.Invalid( - msg, value, state, error_dict={'email': msg} - ) + msg = M(self, "non_existing_email", state, email=value) + raise formencode.Invalid(msg, value, state, error_dict={"email": msg}) + return _validator def NotReviewedRevisions(localizer, repo_id): _ = localizer + class _validator(formencode.validators.FancyValidator): messages = { - 'rev_already_reviewed': - _('Revisions %(revs)s are already part of pull request ' - 'or have set status'), + "rev_already_reviewed": _("Revisions %(revs)s are already part of pull request or have set status"), } def _validate_python(self, value, state): # check revisions if they are not reviewed, or a part of another # pull request - statuses = ChangesetStatus.query()\ - .filter(ChangesetStatus.revision.in_(value))\ - .filter(ChangesetStatus.repo_id == repo_id)\ + statuses = ( + ChangesetStatus.query() + .filter(ChangesetStatus.revision.in_(value)) + .filter(ChangesetStatus.repo_id == repo_id) .all() + ) errors = [] for status in statuses: if status.pull_request_id: - errors.append(['pull_req', status.revision[:12]]) + errors.append(["pull_req", status.revision[:12]]) elif status.status: - errors.append(['status', status.revision[:12]]) + errors.append(["status", status.revision[:12]]) if errors: - revs = ','.join([x[1] for x in errors]) - msg = M(self, 'rev_already_reviewed', state, revs=revs) - raise formencode.Invalid( - msg, value, state, error_dict={'revisions': revs}) + revs = ",".join([x[1] for x in errors]) + msg = M(self, "rev_already_reviewed", state, revs=revs) + raise formencode.Invalid(msg, value, state, error_dict={"revisions": revs}) return _validator @@ -939,10 +881,8 @@ def ValidIp(localizer): class _validator(CIDR): messages = { - 'badFormat': _('Please enter a valid IPv4 or IpV6 address'), - 'illegalBits': _( - 'The network size (bits) must be within the range ' - 'of 0-32 (not %(bits)r)'), + "badFormat": _("Please enter a valid IPv4 or IpV6 address"), + "illegalBits": _("The network size (bits) must be within the range of 0-32 (not %(bits)r)"), } # we override the default to_python() call @@ -958,8 +898,8 @@ def ValidIp(localizer): # this raises an ValueError if address is not IpV4 or IpV6 ipaddress.ip_network(addr, strict=False) except ValueError: - raise formencode.Invalid(self.message('badFormat', state), - value, state) + raise formencode.Invalid(self.message("badFormat", state), value, state) + return _validator @@ -968,15 +908,13 @@ def FieldKey(localizer): class _validator(formencode.validators.FancyValidator): messages = { - 'badFormat': _( - 'Key name can only consist of letters, ' - 'underscore, dash or numbers'), + "badFormat": _("Key name can only consist of letters, underscore, dash or numbers"), } def _validate_python(self, value, state): - if not re.match('[a-zA-Z0-9_-]+$', value): - raise formencode.Invalid(self.message('badFormat', state), - value, state) + if not re.match("[a-zA-Z0-9_-]+$", value): + raise formencode.Invalid(self.message("badFormat", state), value, state) + return _validator @@ -985,21 +923,15 @@ def ValidAuthPlugins(localizer): class _validator(formencode.validators.FancyValidator): messages = { - 'import_duplicate': _( - 'Plugins %(loaded)s and %(next_to_load)s ' - 'both export the same name'), - 'missing_includeme': _( - 'The plugin "%(plugin_id)s" is missing an includeme ' - 'function.'), - 'import_error': _( - 'Can not load plugin "%(plugin_id)s"'), - 'no_plugin': _( - 'No plugin available with ID "%(plugin_id)s"'), + "import_duplicate": _("Plugins %(loaded)s and %(next_to_load)s both export the same name"), + "missing_includeme": _('The plugin "%(plugin_id)s" is missing an includeme function.'), + "import_error": _('Can not load plugin "%(plugin_id)s"'), + "no_plugin": _('No plugin available with ID "%(plugin_id)s"'), } def _convert_to_python(self, value, state): # filter empty values - return [s for s in value if s not in [None, '']] + return [s for s in value if s not in [None, ""]] def _validate_legacy_plugin_id(self, plugin_id, value, state): """ @@ -1009,14 +941,12 @@ def ValidAuthPlugins(localizer): try: plugin = _import_legacy_plugin(plugin_id) except Exception as e: - log.exception( - 'Exception during import of auth legacy plugin "{}"' - .format(plugin_id)) - msg = M(self, 'import_error', state, plugin_id=plugin_id) + log.exception('Exception during import of auth legacy plugin "{}"'.format(plugin_id)) + msg = M(self, "import_error", state, plugin_id=plugin_id) raise formencode.Invalid(msg, value, state) - if not hasattr(plugin, 'includeme'): - msg = M(self, 'missing_includeme', state, plugin_id=plugin_id) + if not hasattr(plugin, "includeme"): + msg = M(self, "missing_includeme", state, plugin_id=plugin_id) raise formencode.Invalid(msg, value, state) return plugin @@ -1030,7 +960,7 @@ def ValidAuthPlugins(localizer): plugin = loadplugin(plugin_id) if plugin is None: - msg = M(self, 'no_plugin', state, plugin_id=plugin_id) + msg = M(self, "no_plugin", state, plugin_id=plugin_id) raise formencode.Invalid(msg, value, state) return plugin @@ -1038,21 +968,18 @@ def ValidAuthPlugins(localizer): def _validate_python(self, value, state): unique_names = {} for plugin_id in value: - # Validate legacy or normal plugin. if plugin_id.startswith(legacy_plugin_prefix): - plugin = self._validate_legacy_plugin_id( - plugin_id, value, state) + plugin = self._validate_legacy_plugin_id(plugin_id, value, state) else: plugin = self._validate_plugin_id(plugin_id, value, state) # Only allow unique plugin names. if plugin.name in unique_names: - msg = M(self, 'import_duplicate', state, - loaded=unique_names[plugin.name], - next_to_load=plugin) + msg = M(self, "import_duplicate", state, loaded=unique_names[plugin.name], next_to_load=plugin) raise formencode.Invalid(msg, value, state) unique_names[plugin.name] = plugin + return _validator @@ -1061,51 +988,46 @@ def ValidPattern(localizer): class _validator(formencode.validators.FancyValidator): messages = { - 'bad_format': _('Url must start with http or /'), + "bad_format": _("Url must start with http or /"), } def _convert_to_python(self, value, state): patterns = [] - prefix = 'new_pattern' + prefix = "new_pattern" for name, v in list(value.items()): - pattern_name = '_'.join((prefix, 'pattern')) + pattern_name = "_".join((prefix, "pattern")) if name.startswith(pattern_name): - new_item_id = name[len(pattern_name)+1:] + new_item_id = name[len(pattern_name) + 1 :] def _field(name): - return '{}_{}_{}'.format(prefix, name, new_item_id) + return "{}_{}_{}".format(prefix, name, new_item_id) values = { - 'issuetracker_pat': value.get(_field('pattern')), - 'issuetracker_url': value.get(_field('url')), - 'issuetracker_pref': value.get(_field('prefix')), - 'issuetracker_desc': value.get(_field('description')) + "issuetracker_pat": value.get(_field("pattern")), + "issuetracker_url": value.get(_field("url")), + "issuetracker_pref": value.get(_field("prefix")), + "issuetracker_desc": value.get(_field("description")), } - new_uid = md5_safe(values['issuetracker_pat']) + new_uid = md5_safe(values["issuetracker_pat"]) - has_required_fields = ( - values['issuetracker_pat'] - and values['issuetracker_url']) + has_required_fields = values["issuetracker_pat"] and values["issuetracker_url"] if has_required_fields: # validate url that it starts with http or / # otherwise it can lead to JS injections # e.g specifig javascript: - if not values['issuetracker_url'].startswith(('http', '/')): - raise formencode.Invalid( - self.message('bad_format', state), - value, state) + if not values["issuetracker_url"].startswith(("http", "/")): + raise formencode.Invalid(self.message("bad_format", state), value, state) - settings = [ - ('_'.join((key, new_uid)), values[key], 'unicode') - for key in values] + settings = [("_".join((key, new_uid)), values[key], "unicode") for key in values] patterns.append(settings) - value['patterns'] = patterns - delete_patterns = value.get('uid') or [] + value["patterns"] = patterns + delete_patterns = value.get("uid") or [] if not isinstance(delete_patterns, (list, tuple)): delete_patterns = [delete_patterns] - value['delete_patterns'] = delete_patterns + value["delete_patterns"] = delete_patterns return value + return _validator diff --git a/rhodecode/subscribers.py b/rhodecode/subscribers.py index c3719898..b0e3c80b 100644 --- a/rhodecode/subscribers.py +++ b/rhodecode/subscribers.py @@ -49,16 +49,17 @@ def add_renderer_globals(event): # TODO: When executed in pyramid view context the request is not available # in the event. Find a better solution to get the request. from rhodecode.lib.pyramid_utils import get_current_request - request = event['request'] or get_current_request() + + request = event["request"] or get_current_request() # Add Pyramid translation as '_' to context - event['_'] = request.translate - event['_ungettext'] = request.plularize - event['h'] = helpers + event["_"] = request.translate + event["_ungettext"] = request.plularize + event["h"] = helpers def auto_merge_pr_if_needed(event): - #TODO To be re-enabled later + # TODO To be re-enabled later pass # from rhodecode.model.db import PullRequest # from rhodecode.model.pull_request import ( @@ -89,17 +90,17 @@ def auto_merge_pr_if_needed(event): def set_user_lang(event): request = event.request - cur_user = getattr(request, 'user', None) + cur_user = getattr(request, "user", None) if cur_user: - user_lang = cur_user.get_instance().user_data.get('language') + user_lang = cur_user.get_instance().user_data.get("language") if user_lang: - log.debug('lang: setting current user:%s language to: %s', cur_user, user_lang) + log.debug("lang: setting current user:%s language to: %s", cur_user, user_lang) event.request._LOCALE_ = user_lang def update_celery_conf(event): - log.debug('Setting celery config from new request') + log.debug("Setting celery config from new request") set_celery_conf(request=event.request, registry=event.request.registry) @@ -112,20 +113,20 @@ def add_request_user_context(event): # access req_id as soon as possible req_id = request.req_id - if hasattr(request, 'vcs_call'): + if hasattr(request, "vcs_call"): # skip vcs calls return - if hasattr(request, 'rpc_method'): + if hasattr(request, "rpc_method"): # skip api calls return auth_user, auth_token = get_auth_user(request) request.user = auth_user request.user_auth_token = auth_token - request.environ['rc_auth_user'] = auth_user - request.environ['rc_auth_user_id'] = str(auth_user.user_id) - request.environ['rc_req_id'] = req_id + request.environ["rc_auth_user"] = auth_user + request.environ["rc_auth_user_id"] = str(auth_user.user_id) + request.environ["rc_req_id"] = req_id def reset_log_bucket(event): @@ -143,12 +144,13 @@ def scan_repositories_if_enabled(event): """ settings = event.app.registry.settings - vcs_server_enabled = settings['vcs.server.enable'] - import_on_startup = settings['startup.import_repos'] + vcs_server_enabled = settings["vcs.server.enable"] + import_on_startup = settings["startup.import_repos"] if vcs_server_enabled and import_on_startup: from rhodecode.model.scm import ScmModel from rhodecode.lib.utils import repo2db_mapper + scm = ScmModel() repositories = scm.repo_scan(scm.repos_path) repo2db_mapper(repositories) @@ -162,53 +164,50 @@ def write_metadata_if_needed(event): from rhodecode.lib import system_info from rhodecode.lib import ext_json - fname = '.rcmetadata.json' - ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__')) + fname = ".rcmetadata.json" + ini_loc = os.path.dirname(rhodecode.CONFIG.get("__file__")) metadata_destination = os.path.join(ini_loc, fname) def get_update_age(): now = datetime.datetime.utcnow() - with open(metadata_destination, 'rb') as f: + with open(metadata_destination, "rb") as f: data = ext_json.json.loads(f.read()) - if 'created_on' in data: - update_date = parse(data['created_on']) + if "created_on" in data: + update_date = parse(data["created_on"]) diff = now - update_date return diff.total_seconds() / 60.0 return 0 def write(): - configuration = system_info.SysInfo( - system_info.rhodecode_config)()['value'] - license_token = configuration['config']['license_token'] + configuration = system_info.SysInfo(system_info.rhodecode_config)()["value"] + license_token = configuration["config"]["license_token"] setup = dict( - workers=configuration['config']['server:main'].get( - 'workers', '?'), - worker_type=configuration['config']['server:main'].get( - 'worker_class', 'sync'), + workers=configuration["config"]["server:main"].get("workers", "?"), + worker_type=configuration["config"]["server:main"].get("worker_class", "sync"), ) - dbinfo = system_info.SysInfo(system_info.database_info)()['value'] - del dbinfo['url'] + dbinfo = system_info.SysInfo(system_info.database_info)()["value"] + del dbinfo["url"] metadata = dict( - desc='upgrade metadata info', + desc="upgrade metadata info", license_token=license_token, created_on=datetime.datetime.utcnow().isoformat(), - usage=system_info.SysInfo(system_info.usage_info)()['value'], - platform=system_info.SysInfo(system_info.platform_type)()['value'], + usage=system_info.SysInfo(system_info.usage_info)()["value"], + platform=system_info.SysInfo(system_info.platform_type)()["value"], database=dbinfo, - cpu=system_info.SysInfo(system_info.cpu)()['value'], - memory=system_info.SysInfo(system_info.memory)()['value'], - setup=setup + cpu=system_info.SysInfo(system_info.cpu)()["value"], + memory=system_info.SysInfo(system_info.memory)()["value"], + setup=setup, ) - with open(metadata_destination, 'wb') as f: + with open(metadata_destination, "wb") as f: f.write(ext_json.json.dumps(metadata)) settings = event.app.registry.settings - if settings.get('metadata.skip'): + if settings.get("metadata.skip"): return # only write this every 24h, workers restart caused unwanted delays @@ -232,28 +231,28 @@ def write_usage_data(event): from rhodecode.lib import ext_json settings = event.app.registry.settings - instance_tag = settings.get('metadata.write_usage_tag') - if not settings.get('metadata.write_usage'): + instance_tag = settings.get("metadata.write_usage_tag") + if not settings.get("metadata.write_usage"): return def get_update_age(dest_file): now = datetime.datetime.now(datetime.UTC) - with open(dest_file, 'rb') as f: + with open(dest_file, "rb") as f: data = ext_json.json.loads(f.read()) - if 'created_on' in data: - update_date = parse(data['created_on']) + if "created_on" in data: + update_date = parse(data["created_on"]) diff = now - update_date return math.ceil(diff.total_seconds() / 60.0) return 0 utc_date = datetime.datetime.now(datetime.UTC) - hour_quarter = int(math.ceil((utc_date.hour + utc_date.minute/60.0) / 6.)) - fname = f'.rc_usage_{utc_date.year}{utc_date.month:02d}{utc_date.day:02d}_{hour_quarter}.json' - ini_loc = os.path.dirname(rhodecode.CONFIG.get('__file__')) + hour_quarter = int(math.ceil((utc_date.hour + utc_date.minute / 60.0) / 6.0)) + fname = f".rc_usage_{utc_date.year}{utc_date.month:02d}{utc_date.day:02d}_{hour_quarter}.json" + ini_loc = os.path.dirname(rhodecode.CONFIG.get("__file__")) - usage_dir = os.path.join(ini_loc, '.rcusage') + usage_dir = os.path.join(ini_loc, ".rcusage") if not os.path.isdir(usage_dir): os.makedirs(usage_dir) usage_metadata_destination = os.path.join(usage_dir, fname) @@ -265,27 +264,26 @@ def write_usage_data(event): # write every 6th hour if age_in_min and age_in_min < 60 * 6: - log.debug('Usage file created %s minutes ago, skipping (threshold: %s minutes)...', - age_in_min, 60 * 6) + log.debug("Usage file created %s minutes ago, skipping (threshold: %s minutes)...", age_in_min, 60 * 6) return def write(dest_file): - configuration = system_info.SysInfo(system_info.rhodecode_config)()['value'] - license_token = configuration['config']['license_token'] + configuration = system_info.SysInfo(system_info.rhodecode_config)()["value"] + license_token = configuration["config"]["license_token"] metadata = dict( - desc='Usage data', + desc="Usage data", instance_tag=instance_tag, license_token=license_token, created_on=datetime.datetime.utcnow().isoformat(), - usage=system_info.SysInfo(system_info.usage_info)()['value'], + usage=system_info.SysInfo(system_info.usage_info)()["value"], ) - with open(dest_file, 'wb') as f: + with open(dest_file, "wb") as f: f.write(ext_json.formatted_json(metadata)) try: - log.debug('Writing usage file at: %s', usage_metadata_destination) + log.debug("Writing usage file at: %s", usage_metadata_destination) write(usage_metadata_destination) except Exception: pass @@ -295,7 +293,7 @@ def write_js_routes_if_enabled(event): registry = event.app.registry mapper = registry.queryUtility(IRoutesMapper) - _argument_prog = re.compile(r'\{(.*?)\}|:\((.*)\)') + _argument_prog = re.compile(r"\{(.*?)\}|:\((.*)\)") def _extract_route_information(route): """ @@ -308,41 +306,39 @@ def write_js_routes_if_enabled(event): def replace(matchobj): if matchobj.group(1): - return "%%(%s)s" % matchobj.group(1).split(':')[0] + return "%%(%s)s" % matchobj.group(1).split(":")[0] else: return "%%(%s)s" % matchobj.group(2) route_path = _argument_prog.sub(replace, route_path) - if not route_path.startswith('/'): - route_path = f'/{route_path}' + if not route_path.startswith("/"): + route_path = f"/{route_path}" return ( route.name, route_path, - [(arg[0].split(':')[0] if arg[0] != '' else arg[1]) - for arg in _argument_prog.findall(pattern)] + [(arg[0].split(":")[0] if arg[0] != "" else arg[1]) for arg in _argument_prog.findall(pattern)], ) def get_routes(): # pyramid routes for route in mapper.get_routes(): - if not route.name.startswith('__'): + if not route.name.startswith("__"): yield _extract_route_information(route) - if asbool(registry.settings.get('generate_js_files', 'false')): - static_path = AssetResolver().resolve('rhodecode:public').abspath() + if asbool(registry.settings.get("generate_js_files", "false")): + static_path = AssetResolver().resolve("rhodecode:public").abspath() jsroutes = get_routes() jsroutes_file_content = generate_jsroutes_content(jsroutes) - jsroutes_file_path = os.path.join( - static_path, 'js', 'rhodecode', 'routes.js') + jsroutes_file_path = os.path.join(static_path, "js", "rhodecode", "routes.js") try: - with open(jsroutes_file_path, 'w', encoding='utf-8') as f: + with open(jsroutes_file_path, "w", encoding="utf-8") as f: f.write(jsroutes_file_content) - log.debug('generated JS files in %s', jsroutes_file_path) + log.debug("generated JS files in %s", jsroutes_file_path) except Exception: - log.exception('Failed to write routes.js into %s', jsroutes_file_path) + log.exception("Failed to write routes.js into %s", jsroutes_file_path) def import_license_if_present(event): @@ -352,30 +348,32 @@ def import_license_if_present(event): """ settings = event.app.registry.settings - rhodecode_edition_id = settings.get('rhodecode.edition_id') - license_file_path = settings.get('license.import_path') - force = settings.get('license.import_path_mode') == 'force' + rhodecode_edition_id = settings.get("rhodecode.edition_id") + license_file_path = settings.get("license.import_path") + force = settings.get("license.import_path_mode") == "force" - if license_file_path and rhodecode_edition_id == 'EE': - log.debug('license.import_path= is set importing license from %s', license_file_path) + if license_file_path and rhodecode_edition_id == "EE": + log.debug("license.import_path= is set importing license from %s", license_file_path) from rhodecode.model.meta import Session from rhodecode.model.license import apply_license_from_file + try: apply_license_from_file(license_file_path, force=force) Session().commit() except OSError: - log.exception('Failed to import license from %s, make sure this file exists', license_file_path) + log.exception("Failed to import license from %s, make sure this file exists", license_file_path) class Subscriber(object): """ Base class for subscribers to the pyramid event system. """ + def __call__(self, event): self.run(event) def run(self, event): - raise NotImplementedError('Subclass has to implement this.') + raise NotImplementedError("Subclass has to implement this.") class AsyncSubscriber(Subscriber): @@ -385,6 +383,7 @@ class AsyncSubscriber(Subscriber): received events into a queue from which the worker process takes them in order. """ + def __init__(self): self._stop = False self._eventq = queue.Queue() @@ -431,22 +430,20 @@ class AsyncSubprocessSubscriber(AsyncSubscriber): def run(self, event): cmd = self._cmd timeout = self._timeout - log.debug('Executing command %s.', cmd) + log.debug("Executing command %s.", cmd) try: - output = subprocess.check_output( - cmd, timeout=timeout, stderr=subprocess.STDOUT) - log.debug('Command finished %s', cmd) + output = subprocess.check_output(cmd, timeout=timeout, stderr=subprocess.STDOUT) + log.debug("Command finished %s", cmd) if output: - log.debug('Command output: %s', output) + log.debug("Command output: %s", output) except subprocess.TimeoutExpired as e: - log.exception('Timeout while executing command.') + log.exception("Timeout while executing command.") if e.output: - log.error('Command output: %s', e.output) + log.error("Command output: %s", e.output) except subprocess.CalledProcessError as e: - log.exception('Error while executing command.') + log.exception("Error while executing command.") if e.output: - log.error('Command output: %s', e.output) + log.error("Command output: %s", e.output) except Exception: - log.exception( - 'Exception while executing command %s.', cmd) + log.exception("Exception while executing command %s.", cmd) diff --git a/rhodecode/tests/__init__.py b/rhodecode/tests/__init__.py index 8188aee9..424d289e 100644 --- a/rhodecode/tests/__init__.py +++ b/rhodecode/tests/__init__.py @@ -33,13 +33,24 @@ from rhodecode.lib import helpers as h from rhodecode.lib.helpers import flash from rhodecode.lib.str_utils import safe_str from rhodecode.lib.hash_utils import sha1_safe -from rhodecode.bootstrap import \ - TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS, TEST_USER_ADMIN_EMAIL, \ - TEST_USER_REGULAR_LOGIN, TEST_USER_REGULAR_PASS, TEST_USER_REGULAR_EMAIL, \ - TEST_USER_REGULAR2_LOGIN, TEST_USER_REGULAR2_PASS, TEST_USER_REGULAR2_EMAIL,\ - HG_REPO, GIT_REPO, SVN_REPO,\ - NEW_HG_REPO, NEW_GIT_REPO,\ - HG_FORK, GIT_FORK +from rhodecode.bootstrap import ( + TEST_USER_ADMIN_LOGIN, + TEST_USER_ADMIN_PASS, + TEST_USER_ADMIN_EMAIL, + TEST_USER_REGULAR_LOGIN, + TEST_USER_REGULAR_PASS, + TEST_USER_REGULAR_EMAIL, + TEST_USER_REGULAR2_LOGIN, + TEST_USER_REGULAR2_PASS, + TEST_USER_REGULAR2_EMAIL, + HG_REPO, + GIT_REPO, + SVN_REPO, + NEW_HG_REPO, + NEW_GIT_REPO, + HG_FORK, + GIT_FORK, +) log = logging.getLogger(__name__) @@ -48,25 +59,26 @@ log = logging.getLogger(__name__) TEST_DIR = tempfile.gettempdir() ## VCS -SCM_TESTS = ['hg', 'git'] +SCM_TESTS = ["hg", "git"] uniq_suffix = str(int(time.mktime(datetime.datetime.now().timetuple()))) -TESTS_TMP_PATH = tempfile.mkdtemp(prefix='rc_test_', dir=TEST_DIR) +TESTS_TMP_PATH = tempfile.mkdtemp(prefix="rc_test_", dir=TEST_DIR) TEST_GIT_REPO = jn(TESTS_TMP_PATH, GIT_REPO) -TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, f'vcsgitclone{uniq_suffix}') -TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, f'vcsgitpull{uniq_suffix}') +TEST_GIT_REPO_CLONE = jn(TESTS_TMP_PATH, f"vcsgitclone{uniq_suffix}") +TEST_GIT_REPO_PULL = jn(TESTS_TMP_PATH, f"vcsgitpull{uniq_suffix}") TEST_HG_REPO = jn(TESTS_TMP_PATH, HG_REPO) -TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, f'vcshgclone{uniq_suffix}') -TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, f'vcshgpull{uniq_suffix}') +TEST_HG_REPO_CLONE = jn(TESTS_TMP_PATH, f"vcshgclone{uniq_suffix}") +TEST_HG_REPO_PULL = jn(TESTS_TMP_PATH, f"vcshgpull{uniq_suffix}") -TEST_REPO_PREFIX = 'vcs-test' +TEST_REPO_PREFIX = "vcs-test" def clear_cache_regions(regions=None): # dogpile from rhodecode.lib.rc_cache import region_meta + for region_name, region in region_meta.dogpile_cache_regions.items(): if not regions or region_name in regions: region.invalidate() @@ -77,12 +89,13 @@ def get_new_dir(title): Returns always new directory path. """ from rhodecode.tests.vcs.utils import get_normalized_path + name_parts = [TEST_REPO_PREFIX] if title: name_parts.append(title) - hex_str = sha1_safe(f'{os.getpid()} {time.time()}') + hex_str = sha1_safe(f"{os.getpid()} {time.time()}") name_parts.append(hex_str) - name = '-'.join(name_parts) + name = "-".join(name_parts) path = jn(TEST_DIR, name) return get_normalized_path(path) @@ -90,22 +103,20 @@ def get_new_dir(title): def repo_id_generator(name): numeric_hash = 0 for char in name: - numeric_hash += (ord(char)) + numeric_hash += ord(char) return numeric_hash -@pytest.mark.usefixtures('app', 'index_location') +@pytest.mark.usefixtures("app", "index_location") class TestController(object): - maxDiff = None - def log_user(self, username=TEST_USER_ADMIN_LOGIN, - password=TEST_USER_ADMIN_PASS): + def log_user(self, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): self._logged_username = username self._session = login_user_session(self.app, username, password) self.csrf_token = auth.get_csrf_token(self._session) - return self._session['rhodecode_user'] + return self._session["rhodecode_user"] def logout_user(self): logout_user_session(self.app, auth.get_csrf_token(self._session)) @@ -117,35 +128,30 @@ class TestController(object): return User.get_by_username(self._logged_username) -def login_user_session( - app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): +def login_user_session(app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): + response = app.post(h.route_path("login"), {"username": username, "password": password}) + if "invalid user name" in response.text: + pytest.fail(f"could not login using {username} {password}") - response = app.post( - h.route_path('login'), - {'username': username, 'password': password}) - if 'invalid user name' in response.text: - pytest.fail(f'could not login using {username} {password}') - - assert response.status == '302 Found' + assert response.status == "302 Found" response = response.follow() - assert response.status == '200 OK' + assert response.status == "200 OK" session = response.get_session_from_response() - assert 'rhodecode_user' in session - rc_user = session['rhodecode_user'] - assert rc_user.get('username') == username - assert rc_user.get('is_authenticated') + assert "rhodecode_user" in session + rc_user = session["rhodecode_user"] + assert rc_user.get("username") == username + assert rc_user.get("is_authenticated") return session def logout_user_session(app, csrf_token): - app.post(h.route_path('logout'), {'csrf_token': csrf_token}, status=302) + app.post(h.route_path("logout"), {"csrf_token": csrf_token}, status=302) -def login_user(app, username=TEST_USER_ADMIN_LOGIN, - password=TEST_USER_ADMIN_PASS): - return login_user_session(app, username, password)['rhodecode_user'] +def login_user(app, username=TEST_USER_ADMIN_LOGIN, password=TEST_USER_ADMIN_PASS): + return login_user_session(app, username, password)["rhodecode_user"] def assert_session_flash(response, msg=None, category=None, no_=None): @@ -172,23 +178,23 @@ def assert_session_flash(response, msg=None, category=None, no_=None): msg = _eval_if_lazy(msg) if no_: - error_msg = f'unable to detect no_ message `{no_}` in empty flash list' + error_msg = f"unable to detect no_ message `{no_}` in empty flash list" else: - error_msg = f'unable to find message `{msg}` in empty flash list' + error_msg = f"unable to find message `{msg}` in empty flash list" assert messages, error_msg message = messages[0] - message_text = _eval_if_lazy(message.message) or '' + message_text = _eval_if_lazy(message.message) or "" if no_: if no_ in message_text: - msg = f'msg `{no_}` found in session flash.' + msg = f"msg `{no_}` found in session flash." pytest.fail(safe_str(msg)) else: - if msg not in message_text: - fail_msg = f'msg `{msg}` not found in ' \ - f'session flash: got `{message_text}` (type:{type(message_text)}) instead' + fail_msg = ( + f"msg `{msg}` not found in session flash: got `{message_text}` (type:{type(message_text)}) instead" + ) pytest.fail(safe_str(fail_msg)) @@ -197,7 +203,7 @@ def assert_session_flash(response, msg=None, category=None, no_=None): def _eval_if_lazy(value): - return value.eval() if hasattr(value, 'eval') else value + return value.eval() if hasattr(value, "eval") else value def no_newline_id_generator(test_name): @@ -206,13 +212,10 @@ def no_newline_id_generator(test_name): nicer output of progress of test """ - test_name = safe_str(test_name)\ - .replace('\n', '_N') \ - .replace('\r', '_N') \ - .replace('\t', '_T') \ - .replace(' ', '_S') + test_name = safe_str(test_name).replace("\n", "_N").replace("\r", "_N").replace("\t", "_T").replace(" ", "_S") + + return test_name or "test-with-empty-name" - return test_name or 'test-with-empty-name' def console_printer(*msg): print_func = print diff --git a/rhodecode/tests/auth_external_test.py b/rhodecode/tests/auth_external_test.py index ab4ff946..efede803 100644 --- a/rhodecode/tests/auth_external_test.py +++ b/rhodecode/tests/auth_external_test.py @@ -22,11 +22,11 @@ External module for testing plugins rhodecode.tests.auth_external_test """ + import logging import traceback -from rhodecode.authentication.base import ( - RhodeCodeExternalAuthPlugin, hybrid_property) +from rhodecode.authentication.base import RhodeCodeExternalAuthPlugin, hybrid_property from rhodecode.model.db import User from rhodecode.lib.ext_json import formatted_json @@ -46,16 +46,15 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): return "external_test" def settings(self): - settings = [ - ] + settings = [] return settings def use_fake_password(self): return True def user_activation_state(self): - def_user_perms = User.get_default_user().AuthUser().permissions['global'] - return 'hg.extern_activate.auto' in def_user_perms + def_user_perms = User.get_default_user().AuthUser().permissions["global"] + return "hg.extern_activate.auto" in def_user_perms def auth(self, userobj, username, password, settings, **kwargs): """ @@ -70,35 +69,35 @@ class RhodeCodeAuthPlugin(RhodeCodeExternalAuthPlugin): """ if not username or not password: - log.debug('Empty username or password skipping...') + log.debug("Empty username or password skipping...") return None try: user_dn = username # # old attrs fetched from RhodeCode database - admin = getattr(userobj, 'admin', False) - active = getattr(userobj, 'active', True) - email = getattr(userobj, 'email', '') - firstname = getattr(userobj, 'firstname', '') - lastname = getattr(userobj, 'lastname', '') - extern_type = getattr(userobj, 'extern_type', '') + admin = getattr(userobj, "admin", False) + active = getattr(userobj, "active", True) + email = getattr(userobj, "email", "") + firstname = getattr(userobj, "firstname", "") + lastname = getattr(userobj, "lastname", "") + extern_type = getattr(userobj, "extern_type", "") # user_attrs = { - 'username': username, - 'firstname': firstname, - 'lastname': lastname, - 'groups': [], - 'email': f'{username}@rhodecode.com', - 'admin': admin, - 'active': active, + "username": username, + "firstname": firstname, + "lastname": lastname, + "groups": [], + "email": f"{username}@rhodecode.com", + "admin": admin, + "active": active, "active_from_extern": None, - 'extern_name': user_dn, - 'extern_type': extern_type, + "extern_name": user_dn, + "extern_type": extern_type, } - log.debug('EXTERNAL user: \n%s', formatted_json(user_attrs)) - log.info('user `%s` authenticated correctly', user_attrs['username']) + log.debug("EXTERNAL user: \n%s", formatted_json(user_attrs)) + log.info("user `%s` authenticated correctly", user_attrs["username"]) return user_attrs diff --git a/rhodecode/tests/config/test_environment.py b/rhodecode/tests/config/test_environment.py index 22c38cf8..551401e7 100644 --- a/rhodecode/tests/config/test_environment.py +++ b/rhodecode/tests/config/test_environment.py @@ -27,18 +27,15 @@ from rhodecode.config import environment def _external_calls_patcher(request): # TODO: mikhail: This is a temporary solution. Ideally load_environment # should be split into multiple small testable functions. - utils_patcher = mock.patch.object(environment, 'utils') + utils_patcher = mock.patch.object(environment, "utils") - rhodecode_patcher = mock.patch.object(environment, 'rhodecode') + rhodecode_patcher = mock.patch.object(environment, "rhodecode") db_config = mock.Mock() - db_config.items.return_value = { - 'paths': [['/tmp/abc', '/tmp/def']] - } - db_config_patcher = mock.patch.object( - environment, 'make_db_config', return_value=db_config) + db_config.items.return_value = {"paths": [["/tmp/abc", "/tmp/def"]]} + db_config_patcher = mock.patch.object(environment, "make_db_config", return_value=db_config) - set_config_patcher = mock.patch.object(environment, 'set_rhodecode_config') + set_config_patcher = mock.patch.object(environment, "set_rhodecode_config") utils_patcher.start() rhodecode_patcher.start() diff --git a/rhodecode/tests/config/test_routing_links.py b/rhodecode/tests/config/test_routing_links.py index 3b6a8588..ca2633bb 100644 --- a/rhodecode/tests/config/test_routing_links.py +++ b/rhodecode/tests/config/test_routing_links.py @@ -21,9 +21,10 @@ import requests from rhodecode.config import routing_links from rhodecode.tests import console_printer + def check_connection(): try: - response = requests.get('https://rhodecode.com') + response = requests.get("https://rhodecode.com") return response.status_code == 200 except Exception as e: console_printer(e) @@ -31,8 +32,7 @@ def check_connection(): return False -connection_available = pytest.mark.skipif( - not check_connection(), reason="No outside internet connection available") +connection_available = pytest.mark.skipif(not check_connection(), reason="No outside internet connection available") import requests @@ -55,17 +55,17 @@ def requests_retry_session( status_forcelist=status_forcelist, ) adapter = HTTPAdapter(max_retries=retry) - session.mount('http://', adapter) - session.mount('https://', adapter) + session.mount("http://", adapter) + session.mount("https://", adapter) return session @connection_available -@pytest.mark.parametrize('link_data', routing_links.link_config) +@pytest.mark.parametrize("link_data", routing_links.link_config) def test_connect_redirection_links(link_data): - response = requests_retry_session().get(link_data['target']) - if link_data['name'] == 'enterprise_license_convert_from_old': + response = requests_retry_session().get(link_data["target"]) + if link_data["name"] == "enterprise_license_convert_from_old": # special case for a page that requires a valid login - assert response.url == 'https://rhodecode.com/login' + assert response.url == "https://rhodecode.com/login" else: - assert response.url == link_data['external_target'] + assert response.url == link_data["external_target"] diff --git a/rhodecode/tests/config/test_sanitize_settings.py b/rhodecode/tests/config/test_sanitize_settings.py index 92206509..41dc8ecf 100644 --- a/rhodecode/tests/config/test_sanitize_settings.py +++ b/rhodecode/tests/config/test_sanitize_settings.py @@ -25,81 +25,110 @@ from rhodecode.config.settings_maker import SettingsMaker class TestHelperFunctions(object): - @pytest.mark.parametrize('raw, expected', [ - ('true', True), (u'true', True), - ('yes', True), (u'yes', True), - ('on', True), (u'on', True), - ('false', False), (u'false', False), - ('no', False), (u'no', False), - ('off', False), (u'off', False), - ('invalid-bool-value', False), - ('invalid-∫øø@-√å@¨€', False), - (u'invalid-∫øø@-√å@¨€', False), - ]) + @pytest.mark.parametrize( + "raw, expected", + [ + ("true", True), + ("true", True), + ("yes", True), + ("yes", True), + ("on", True), + ("on", True), + ("false", False), + ("false", False), + ("no", False), + ("no", False), + ("off", False), + ("off", False), + ("invalid-bool-value", False), + ("invalid-∫øø@-√å@¨€", False), + ("invalid-∫øø@-√å@¨€", False), + ], + ) def test_bool_func_helper(self, raw, expected): val = SettingsMaker._bool_func(raw) assert val == expected - @pytest.mark.parametrize('raw, expected', [ - ('', ''), - ('test-string', 'test-string'), - ('CaSe-TeSt', 'case-test'), - ('test-string-烩€', 'test-string-烩€'), - (u'test-string-烩€', u'test-string-烩€'), - ]) + @pytest.mark.parametrize( + "raw, expected", + [ + ("", ""), + ("test-string", "test-string"), + ("CaSe-TeSt", "case-test"), + ("test-string-烩€", "test-string-烩€"), + ("test-string-烩€", "test-string-烩€"), + ], + ) def test_string_func_helper(self, raw, expected): val = SettingsMaker._string_func(raw) assert val == expected - @pytest.mark.parametrize('raw, expected', [ - ('', []), - ('test', ['test']), - ('CaSe-TeSt', ['CaSe-TeSt']), - ('test-string-烩€', ['test-string-烩€']), - (u'test-string-烩€', [u'test-string-烩€']), - ('hg,git,svn', ['hg', 'git', 'svn']), - ('hg, git, svn', ['hg', 'git', 'svn']), - - (', hg , git , svn , ', ['', 'hg', 'git', 'svn', '']), - ('cheese,free node,other', ['cheese', 'free node', 'other']), - ], ids=no_newline_id_generator) + @pytest.mark.parametrize( + "raw, expected", + [ + ("", []), + ("test", ["test"]), + ("CaSe-TeSt", ["CaSe-TeSt"]), + ("test-string-烩€", ["test-string-烩€"]), + ("test-string-烩€", ["test-string-烩€"]), + ("hg,git,svn", ["hg", "git", "svn"]), + ("hg, git, svn", ["hg", "git", "svn"]), + (", hg , git , svn , ", ["", "hg", "git", "svn", ""]), + ("cheese,free node,other", ["cheese", "free node", "other"]), + ], + ids=no_newline_id_generator, + ) def test_list_setting_helper(self, raw, expected): val = SettingsMaker._list_func(raw) assert val == expected - @pytest.mark.parametrize('raw, expected', [ - ('hg git svn', ['hg', 'git', 'svn']), - ], ids=no_newline_id_generator) + @pytest.mark.parametrize( + "raw, expected", + [ + ("hg git svn", ["hg", "git", "svn"]), + ], + ids=no_newline_id_generator, + ) def test_list_setting_spaces_helper(self, raw, expected): - val = SettingsMaker._list_func(raw, sep=' ') + val = SettingsMaker._list_func(raw, sep=" ") assert val == expected - @pytest.mark.parametrize('raw, expected', [ - ('hg\ngit\nsvn', ['hg', 'git', 'svn']), - (' hg\n git\n svn ', ['hg', 'git', 'svn']), - ], ids=no_newline_id_generator) + @pytest.mark.parametrize( + "raw, expected", + [ + ("hg\ngit\nsvn", ["hg", "git", "svn"]), + (" hg\n git\n svn ", ["hg", "git", "svn"]), + ], + ids=no_newline_id_generator, + ) def test_list_setting_newlines_helper(self, raw, expected): - val = SettingsMaker._list_func(raw, sep='\n') + val = SettingsMaker._list_func(raw, sep="\n") assert val == expected - @pytest.mark.parametrize('raw, expected', [ - ('0', 0), - ('-0', 0), - ('12345', 12345), - ('-12345', -12345), - (u'-12345', -12345), - ]) + @pytest.mark.parametrize( + "raw, expected", + [ + ("0", 0), + ("-0", 0), + ("12345", 12345), + ("-12345", -12345), + ("-12345", -12345), + ], + ) def test_int_setting_helper(self, raw, expected): val = SettingsMaker._int_func(raw) assert val == expected - @pytest.mark.parametrize('raw', [ - ('0xff'), - (''), - ('invalid-int'), - ('invalid-⁄~†'), - (u'invalid-⁄~†'), - ]) + @pytest.mark.parametrize( + "raw", + [ + ("0xff"), + (""), + ("invalid-int"), + ("invalid-⁄~†"), + ("invalid-⁄~†"), + ], + ) def test_int_setting_helper_invalid_input(self, raw): with pytest.raises(Exception): SettingsMaker._int_func(raw) @@ -107,23 +136,23 @@ class TestHelperFunctions(object): class TestSanitizeVcsSettings(object): _bool_funcs = [ - ('vcs.hooks.direct_calls', False), - ('vcs.server.enable', True), - ('vcs.start_server', False), - ('startup.import_repos', False), + ("vcs.hooks.direct_calls", False), + ("vcs.server.enable", True), + ("vcs.start_server", False), + ("startup.import_repos", False), ] _string_funcs = [ - ('vcs.svn.compatible_version', ''), - ('vcs.hooks.protocol.v2', 'celery'), - ('vcs.hooks.host', '*'), - ('vcs.scm_app_implementation', 'http'), - ('vcs.server', ''), - ('vcs.server.protocol', 'http'), + ("vcs.svn.compatible_version", ""), + ("vcs.hooks.protocol.v2", "celery"), + ("vcs.hooks.host", "*"), + ("vcs.scm_app_implementation", "http"), + ("vcs.server", ""), + ("vcs.server.protocol", "http"), ] _list_settings = [ - ('vcs.backends', 'hg git'), + ("vcs.backends", "hg git"), ] # @pytest.mark.parametrize('key, default', _list_settings) @@ -142,33 +171,33 @@ class TestSanitizeVcsSettings(object): # sanitize_settings_and_apply_defaults({'__file__': ''}, settings) # assert settings[key] == test_list - @pytest.mark.parametrize('key, default', _list_settings) + @pytest.mark.parametrize("key, default", _list_settings) def test_list_setting_commasep_list(self, key, default): - test_list = ['test', 'list', 'values', 'for', key] - input_value = ','.join(test_list) + test_list = ["test", "list", "values", "for", key] + input_value = ",".join(test_list) settings = {key: input_value} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] == test_list - @pytest.mark.parametrize('key, default', _list_settings) + @pytest.mark.parametrize("key, default", _list_settings) def test_list_setting_comma_and_space_sep_list(self, key, default): - test_list = ['test', 'list', 'values', 'for', key] - input_value = ', '.join(test_list) + test_list = ["test", "list", "values", "for", key] + input_value = ", ".join(test_list) settings = {key: input_value} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] == test_list - @pytest.mark.parametrize('key, default', _string_funcs) + @pytest.mark.parametrize("key, default", _string_funcs) def test_string_func_string(self, key, default): - test_value = 'test-string-for-{}'.format(key) + test_value = "test-string-for-{}".format(key) settings = {key: test_value} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] == test_value - @pytest.mark.parametrize('key, default', _string_funcs) + @pytest.mark.parametrize("key, default", _string_funcs) def test_string_func_default(self, key, default): settings = {} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] == default # @pytest.mark.parametrize('key, default', _string_funcs) @@ -178,26 +207,26 @@ class TestSanitizeVcsSettings(object): # sanitize_settings_and_apply_defaults({'__file__': ''}, settings) # assert settings[key] == test_value.lower() - @pytest.mark.parametrize('key, default', _bool_funcs) + @pytest.mark.parametrize("key, default", _bool_funcs) def test_bool_func_true(self, key, default): - settings = {key: 'true'} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + settings = {key: "true"} + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] is True - @pytest.mark.parametrize('key, default', _bool_funcs) + @pytest.mark.parametrize("key, default", _bool_funcs) def test_bool_func_false(self, key, default): - settings = {key: 'false'} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + settings = {key: "false"} + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] is False - @pytest.mark.parametrize('key, default', _bool_funcs) + @pytest.mark.parametrize("key, default", _bool_funcs) def test_bool_func_invalid_string(self, key, default): - settings = {key: 'no-bool-val-string'} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + settings = {key: "no-bool-val-string"} + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] is False - @pytest.mark.parametrize('key, default', _bool_funcs) + @pytest.mark.parametrize("key, default", _bool_funcs) def test_bool_func_default(self, key, default): settings = {} - sanitize_settings_and_apply_defaults({'__file__': ''}, settings) + sanitize_settings_and_apply_defaults({"__file__": ""}, settings) assert settings[key] is default diff --git a/rhodecode/tests/config/test_utils.py b/rhodecode/tests/config/test_utils.py index 285567d8..806a4698 100644 --- a/rhodecode/tests/config/test_utils.py +++ b/rhodecode/tests/config/test_utils.py @@ -21,14 +21,14 @@ import pytest from rhodecode.config.utils import set_instance_id -@pytest.mark.parametrize('instance_id', ['', None, '*', 'custom-id']) +@pytest.mark.parametrize("instance_id", ["", None, "*", "custom-id"]) def test_set_instance_id(instance_id): - config = {'instance_id': instance_id} + config = {"instance_id": instance_id} set_instance_id(config) - if instance_id == 'custom-id': - assert config['instance_id'] == instance_id + if instance_id == "custom-id": + assert config["instance_id"] == instance_id else: - assert isinstance(config['instance_id'], str) - assert len(config['instance_id']) - assert instance_id != config['instance_id'] + assert isinstance(config["instance_id"], str) + assert len(config["instance_id"]) + assert instance_id != config["instance_id"] diff --git a/rhodecode/tests/conftest.py b/rhodecode/tests/conftest.py index da5ca2af..25520a6f 100644 --- a/rhodecode/tests/conftest.py +++ b/rhodecode/tests/conftest.py @@ -16,7 +16,7 @@ # RhodeCode Enterprise Edition, including its added features, Support services, # and proprietary license terms, please see https://rhodecode.com/licenses/ -import pytest # noqa +import pytest # noqa import logging import collections import rhodecode @@ -25,5 +25,5 @@ import rhodecode log = logging.getLogger(__name__) # Docker image running httpbin... -HTTPBIN_DOMAIN = 'http://httpbin' -HTTPBIN_POST = HTTPBIN_DOMAIN + '/post' +HTTPBIN_DOMAIN = "http://httpbin" +HTTPBIN_POST = HTTPBIN_DOMAIN + "/post" diff --git a/rhodecode/tests/conftest_common.py b/rhodecode/tests/conftest_common.py index 20d044a5..c60635a0 100644 --- a/rhodecode/tests/conftest_common.py +++ b/rhodecode/tests/conftest_common.py @@ -20,108 +20,125 @@ from rhodecode.lib import ext_json def get_backends_from_metafunc(metafunc): - requested_backends = set(metafunc.config.getoption('--backends')) - backend_mark = metafunc.definition.get_closest_marker('backends') + requested_backends = set(metafunc.config.getoption("--backends")) + backend_mark = metafunc.definition.get_closest_marker("backends") if backend_mark: # Supported backends by this test function, created from # pytest.mark.backends backends = backend_mark.args - elif hasattr(metafunc.cls, 'backend_alias'): + elif hasattr(metafunc.cls, "backend_alias"): # Support class attribute "backend_alias", this is mainly # for legacy reasons for tests not yet using pytest.mark.backends backends = [metafunc.cls.backend_alias] else: - backends = metafunc.config.getoption('--backends') + backends = metafunc.config.getoption("--backends") return requested_backends.intersection(backends) def pytest_addoption(parser): - def _parse_json(value): return ext_json.str_json(value) if value else None def _split_comma(value): - return value.split(',') + return value.split(",") + + parser.addoption("--keep-tmp-path", action="store_true", help="Keep the test temporary directories") parser.addoption( - '--keep-tmp-path', action='store_true', - help="Keep the test temporary directories") - - parser.addoption( - '--backends', action='store', type=_split_comma, - default=['git', 'hg', 'svn'], - help="Select which backends to test for backend specific tests.") - parser.addoption( - '--dbs', action='store', type=_split_comma, - default=['sqlite'], - help="Select which database to test for database specific tests. " - "Possible options are sqlite,postgres,mysql") - parser.addoption( - '--appenlight', '--ae', action='store_true', - help="Track statistics in appenlight.") - parser.addoption( - '--appenlight-api-key', '--ae-key', - help="API key for Appenlight.") - parser.addoption( - '--appenlight-url', '--ae-url', - default="https://ae.rhodecode.com", - help="Appenlight service URL, defaults to https://ae.rhodecode.com") - parser.addoption( - '--sqlite-connection-string', action='store', - default='', help="Connection string for the dbs tests with SQLite") - parser.addoption( - '--postgres-connection-string', action='store', - default='', help="Connection string for the dbs tests with Postgres") - parser.addoption( - '--mysql-connection-string', action='store', - default='', help="Connection string for the dbs tests with MySQL") - parser.addoption( - '--repeat', type=int, default=100, - help="Number of repetitions in performance tests.") - - parser.addoption( - '--test-loglevel', dest='test_loglevel', - help="Set default Logging level for tests, critical(default), error, warn , info, debug") - - group = parser.getgroup('pyramid') - group.addoption( - '--pyramid-config', dest='pyramid_config', - help="Set up a pyramid with the specified ini config file.") - group.addoption( - '--ini-config-override', action='store', type=_parse_json, - default=None, dest='pyramid_config_override', help=( - "Overrides the .ini file settings. Should be specified in JSON" - " format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'" - ) + "--backends", + action="store", + type=_split_comma, + default=["git", "hg", "svn"], + help="Select which backends to test for backend specific tests.", ) - parser.addini( - 'pyramid_config', - "Set up a Pyramid environment with the specified config file.") + parser.addoption( + "--dbs", + action="store", + type=_split_comma, + default=["sqlite"], + help="Select which database to test for database specific tests. Possible options are sqlite,postgres,mysql", + ) + parser.addoption("--appenlight", "--ae", action="store_true", help="Track statistics in appenlight.") + parser.addoption("--appenlight-api-key", "--ae-key", help="API key for Appenlight.") + parser.addoption( + "--appenlight-url", + "--ae-url", + default="https://ae.rhodecode.com", + help="Appenlight service URL, defaults to https://ae.rhodecode.com", + ) + parser.addoption( + "--sqlite-connection-string", action="store", default="", help="Connection string for the dbs tests with SQLite" + ) + parser.addoption( + "--postgres-connection-string", + action="store", + default="", + help="Connection string for the dbs tests with Postgres", + ) + parser.addoption( + "--mysql-connection-string", action="store", default="", help="Connection string for the dbs tests with MySQL" + ) + parser.addoption("--repeat", type=int, default=100, help="Number of repetitions in performance tests.") - parser.addini('rhodecode_config', 'rhodecode config ini for tests') - parser.addini('celery_config', 'celery config ini for tests') - parser.addini('vcsserver_config', 'vcsserver config ini for tests') + parser.addoption( + "--test-loglevel", + dest="test_loglevel", + help="Set default Logging level for tests, critical(default), error, warn , info, debug", + ) - vcsgroup = parser.getgroup('vcs') + group = parser.getgroup("pyramid") + group.addoption( + "--pyramid-config", dest="pyramid_config", help="Set up a pyramid with the specified ini config file." + ) + group.addoption( + "--ini-config-override", + action="store", + type=_parse_json, + default=None, + dest="pyramid_config_override", + help=( + "Overrides the .ini file settings. Should be specified in JSON" + ' format, e.g. \'{"section": {"parameter": "value", ...}}\'' + ), + ) + parser.addini("pyramid_config", "Set up a Pyramid environment with the specified config file.") + + parser.addini("rhodecode_config", "rhodecode config ini for tests") + parser.addini("celery_config", "celery config ini for tests") + parser.addini("vcsserver_config", "vcsserver config ini for tests") + + vcsgroup = parser.getgroup("vcs") vcsgroup.addoption( - '--without-vcsserver', dest='with_vcsserver', action='store_false', - help="Do not start the VCSServer in a background process.") + "--without-vcsserver", + dest="with_vcsserver", + action="store_false", + help="Do not start the VCSServer in a background process.", + ) vcsgroup.addoption( - '--vcsserver-config-override', action='store', type=_parse_json, - default=None, dest='vcsserver_config_override', help=( + "--vcsserver-config-override", + action="store", + type=_parse_json, + default=None, + dest="vcsserver_config_override", + help=( "Overrides the .ini file settings for the VCSServer. " "Should be specified in JSON " - "format, e.g. '{\"section\": {\"parameter\": \"value\", ...}}'" - ) + 'format, e.g. \'{"section": {"parameter": "value", ...}}\'' + ), ) vcsgroup.addoption( - '--vcsserver-port', action='store', type=int, - default=None, help=( + "--vcsserver-port", + action="store", + type=int, + default=None, + help=( "Allows to set the port of the vcsserver. Useful when testing " "against an already running server and random ports cause " - "trouble.")) + "trouble." + ), + ) @pytest.hookimpl(tryfirst=True, hookwrapper=True) @@ -137,25 +154,24 @@ def pytest_runtest_makereport(item, call): if call.excinfo: exc = call.excinfo.value - vcsserver_traceback = getattr(exc, '_vcs_server_traceback', None) + vcsserver_traceback = getattr(exc, "_vcs_server_traceback", None) - if vcsserver_traceback and report.outcome == 'failed': - section = f'VCSServer remote traceback {report.when}' + if vcsserver_traceback and report.outcome == "failed": + section = f"VCSServer remote traceback {report.when}" report.sections.append((section, vcsserver_traceback)) def pytest_generate_tests(metafunc): - # Support test generation based on --backend parameter - if 'backend_alias' in metafunc.fixturenames: + if "backend_alias" in metafunc.fixturenames: backends = get_backends_from_metafunc(metafunc) scope = None if not backends: pytest.skip("Not enabled for any of selected backends") - metafunc.parametrize('backend_alias', backends, scope=scope) + metafunc.parametrize("backend_alias", backends, scope=scope) - backend_mark = metafunc.definition.get_closest_marker('backends') + backend_mark = metafunc.definition.get_closest_marker("backends") if backend_mark: backends = get_backends_from_metafunc(metafunc) if not backends: diff --git a/rhodecode/tests/events/conftest.py b/rhodecode/tests/events/conftest.py index 60d0a60f..79e545ac 100644 --- a/rhodecode/tests/events/conftest.py +++ b/rhodecode/tests/events/conftest.py @@ -21,14 +21,14 @@ import decorator class EventCatcher(object): - """ Testing context manager to check if events are fired """ + """Testing context manager to check if events are fired""" def __init__(self): - self.events = [] # the actual events captured - self.events_types = [] # the types of events captured + self.events = [] # the actual events captured + self.events_types = [] # the types of events captured def __enter__(self): - self.event_trigger_patch = mock.patch('rhodecode.events.trigger') + self.event_trigger_patch = mock.patch("rhodecode.events.trigger") self.mocked_event_trigger = self.event_trigger_patch.start() return self diff --git a/rhodecode/tests/events/test_pullrequest.py b/rhodecode/tests/events/test_pullrequest.py index 4a021d51..cda47db7 100644 --- a/rhodecode/tests/events/test_pullrequest.py +++ b/rhodecode/tests/events/test_pullrequest.py @@ -32,27 +32,31 @@ from rhodecode.events import ( PullRequestCloseEvent, ) + # TODO: dan: make the serialization tests complete json comparisons @pytest.mark.backends("git", "hg") -@pytest.mark.parametrize('EventClass', [ - PullRequestCreateEvent, - PullRequestUpdateEvent, - PullRequestReviewEvent, - PullRequestMergeEvent, - PullRequestCloseEvent -]) +@pytest.mark.parametrize( + "EventClass", + [ + PullRequestCreateEvent, + PullRequestUpdateEvent, + PullRequestReviewEvent, + PullRequestMergeEvent, + PullRequestCloseEvent, + ], +) def test_pullrequest_events_serialized(EventClass, pr_util, config_stub): pr = pr_util.create_pull_request() if EventClass == PullRequestReviewEvent: - event = EventClass(pr, 'approved') + event = EventClass(pr, "approved") else: event = EventClass(pr) data = event.as_dict() - assert data['name'] == EventClass.name - assert data['repo']['repo_name'] == pr.target_repo.repo_name - assert data['pullrequest']['pull_request_id'] == pr.pull_request_id - assert data['pullrequest']['url'] - assert data['pullrequest']['permalink_url'] + assert data["name"] == EventClass.name + assert data["repo"]["repo_name"] == pr.target_repo.repo_name + assert data["pullrequest"]["pull_request_id"] == pr.pull_request_id + assert data["pullrequest"]["url"] + assert data["pullrequest"]["permalink_url"] @pytest.mark.backends("git", "hg") @@ -66,31 +70,29 @@ def test_create_pull_request_events(pr_util, config_stub): @pytest.mark.backends("git", "hg") def test_pullrequest_comment_events_serialized(pr_util, config_stub): pr = pr_util.create_pull_request() - comment = CommentsModel().get_comments( - pr.target_repo.repo_id, pull_request=pr)[0] + comment = CommentsModel().get_comments(pr.target_repo.repo_id, pull_request=pr)[0] event = PullRequestCommentEvent(pr, comment) data = event.as_dict() - assert data['name'] == PullRequestCommentEvent.name - assert data['repo']['repo_name'] == pr.target_repo.repo_name - assert data['pullrequest']['pull_request_id'] == pr.pull_request_id - assert data['pullrequest']['url'] - assert data['pullrequest']['permalink_url'] - assert data['comment']['text'] == comment.text + assert data["name"] == PullRequestCommentEvent.name + assert data["repo"]["repo_name"] == pr.target_repo.repo_name + assert data["pullrequest"]["pull_request_id"] == pr.pull_request_id + assert data["pullrequest"]["url"] + assert data["pullrequest"]["permalink_url"] + assert data["comment"]["text"] == comment.text @pytest.mark.backends("git", "hg") def test_pullrequest_comment_edit_events_serialized(pr_util, config_stub): pr = pr_util.create_pull_request() - comment = CommentsModel().get_comments( - pr.target_repo.repo_id, pull_request=pr)[0] + comment = CommentsModel().get_comments(pr.target_repo.repo_id, pull_request=pr)[0] event = PullRequestCommentEditEvent(pr, comment) data = event.as_dict() - assert data['name'] == PullRequestCommentEditEvent.name - assert data['repo']['repo_name'] == pr.target_repo.repo_name - assert data['pullrequest']['pull_request_id'] == pr.pull_request_id - assert data['pullrequest']['url'] - assert data['pullrequest']['permalink_url'] - assert data['comment']['text'] == comment.text + assert data["name"] == PullRequestCommentEditEvent.name + assert data["repo"]["repo_name"] == pr.target_repo.repo_name + assert data["pullrequest"]["pull_request_id"] == pr.pull_request_id + assert data["pullrequest"]["url"] + assert data["pullrequest"]["permalink_url"] + assert data["comment"]["text"] == comment.text @pytest.mark.backends("git", "hg") @@ -108,7 +110,6 @@ def test_close_pull_request_with_comment_events(pr_util, user_admin, config_stub pr = pr_util.create_pull_request() with EventCatcher() as event_catcher: - PullRequestModel().close_pull_request_with_comment( - pr, user_admin, pr.target_repo) + PullRequestModel().close_pull_request_with_comment(pr, user_admin, pr.target_repo) assert PullRequestCloseEvent in event_catcher.events_types diff --git a/rhodecode/tests/events/test_repo.py b/rhodecode/tests/events/test_repo.py index 3b62545d..6e146f77 100644 --- a/rhodecode/tests/events/test_repo.py +++ b/rhodecode/tests/events/test_repo.py @@ -25,72 +25,80 @@ from rhodecode.tests.events.conftest import EventCatcher from rhodecode.lib import hooks_base, utils2 from rhodecode.model.repo import RepoModel from rhodecode.events.repo import ( - RepoPrePullEvent, RepoPullEvent, - RepoPrePushEvent, RepoPushEvent, - RepoPreCreateEvent, RepoCreateEvent, - RepoPreDeleteEvent, RepoDeleteEvent, - RepoCommitCommentEvent, RepoCommitCommentEditEvent + RepoPrePullEvent, + RepoPullEvent, + RepoPrePushEvent, + RepoPushEvent, + RepoPreCreateEvent, + RepoCreateEvent, + RepoPreDeleteEvent, + RepoDeleteEvent, + RepoCommitCommentEvent, + RepoCommitCommentEditEvent, ) @pytest.fixture() def scm_extras(user_regular, repo_stub): - extras = utils2.AttributeDict({ - 'ip': '127.0.0.1', - 'username': user_regular.username, - 'user_id': user_regular.user_id, - 'action': '', - 'repository': repo_stub.repo_name, - 'scm': repo_stub.scm_instance().alias, - 'config': '', - 'repo_store': '', - 'server_url': 'http://example.com', - 'make_lock': None, - 'user_agent': 'some-client', - 'locked_by': [None], - 'commit_ids': ['a' * 40] * 3, - 'hook_type': 'scm_extras_test', - 'is_shadow_repo': False, - }) + extras = utils2.AttributeDict( + { + "ip": "127.0.0.1", + "username": user_regular.username, + "user_id": user_regular.user_id, + "action": "", + "repository": repo_stub.repo_name, + "scm": repo_stub.scm_instance().alias, + "config": "", + "repo_store": "", + "server_url": "http://example.com", + "make_lock": None, + "user_agent": "some-client", + "locked_by": [None], + "commit_ids": ["a" * 40] * 3, + "hook_type": "scm_extras_test", + "is_shadow_repo": False, + } + ) return extras # TODO: dan: make the serialization tests complete json comparisons -@pytest.mark.parametrize('EventClass', [ - RepoPreCreateEvent, RepoCreateEvent, - RepoPreDeleteEvent, RepoDeleteEvent, -]) +@pytest.mark.parametrize( + "EventClass", + [ + RepoPreCreateEvent, + RepoCreateEvent, + RepoPreDeleteEvent, + RepoDeleteEvent, + ], +) def test_repo_events_serialized(config_stub, repo_stub, EventClass): event = EventClass(repo_stub) data = event.as_dict() - assert data['name'] == EventClass.name - assert data['repo']['repo_name'] == repo_stub.repo_name - assert data['repo']['url'] - assert data['repo']['permalink_url'] + assert data["name"] == EventClass.name + assert data["repo"]["repo_name"] == repo_stub.repo_name + assert data["repo"]["url"] + assert data["repo"]["permalink_url"] -@pytest.mark.parametrize('EventClass', [ - RepoPrePullEvent, RepoPullEvent, RepoPrePushEvent -]) +@pytest.mark.parametrize("EventClass", [RepoPrePullEvent, RepoPullEvent, RepoPrePushEvent]) def test_vcs_repo_events_serialize(config_stub, repo_stub, scm_extras, EventClass): event = EventClass(repo_name=repo_stub.repo_name, extras=scm_extras) data = event.as_dict() - assert data['name'] == EventClass.name - assert data['repo']['repo_name'] == repo_stub.repo_name - assert data['repo']['url'] - assert data['repo']['permalink_url'] + assert data["name"] == EventClass.name + assert data["repo"]["repo_name"] == repo_stub.repo_name + assert data["repo"]["url"] + assert data["repo"]["permalink_url"] -@pytest.mark.parametrize('EventClass', [RepoPushEvent]) +@pytest.mark.parametrize("EventClass", [RepoPushEvent]) def test_vcs_repo_push_event_serialize(config_stub, repo_stub, scm_extras, EventClass): - event = EventClass(repo_name=repo_stub.repo_name, - pushed_commit_ids=scm_extras['commit_ids'], - extras=scm_extras) + event = EventClass(repo_name=repo_stub.repo_name, pushed_commit_ids=scm_extras["commit_ids"], extras=scm_extras) data = event.as_dict() - assert data['name'] == EventClass.name - assert data['repo']['repo_name'] == repo_stub.repo_name - assert data['repo']['url'] - assert data['repo']['permalink_url'] + assert data["name"] == EventClass.name + assert data["repo"]["repo_name"] == repo_stub.repo_name + assert data["repo"]["url"] + assert data["repo"]["permalink_url"] def test_create_delete_repo_fires_events(backend): @@ -123,47 +131,53 @@ def test_push_fires_events(scm_extras): assert event_catcher.events_types == [RepoPullEvent] -@pytest.mark.parametrize('EventClass', [RepoCommitCommentEvent]) +@pytest.mark.parametrize("EventClass", [RepoCommitCommentEvent]) def test_repo_commit_event(config_stub, repo_stub, EventClass): + commit = StrictAttributeDict( + { + "raw_id": "raw_id", + "message": "message", + "branch": "branch", + } + ) - commit = StrictAttributeDict({ - 'raw_id': 'raw_id', - 'message': 'message', - 'branch': 'branch', - }) - - comment = StrictAttributeDict({ - 'comment_id': 'comment_id', - 'text': 'text', - 'comment_type': 'comment_type', - 'f_path': 'f_path', - 'line_no': 'line_no', - 'last_version': 0, - }) + comment = StrictAttributeDict( + { + "comment_id": "comment_id", + "text": "text", + "comment_type": "comment_type", + "f_path": "f_path", + "line_no": "line_no", + "last_version": 0, + } + ) event = EventClass(repo=repo_stub, commit=commit, comment=comment) data = event.as_dict() - assert data['commit']['commit_id'] - assert data['comment']['comment_id'] + assert data["commit"]["commit_id"] + assert data["comment"]["comment_id"] -@pytest.mark.parametrize('EventClass', [RepoCommitCommentEditEvent]) +@pytest.mark.parametrize("EventClass", [RepoCommitCommentEditEvent]) def test_repo_commit_edit_event(config_stub, repo_stub, EventClass): + commit = StrictAttributeDict( + { + "raw_id": "raw_id", + "message": "message", + "branch": "branch", + } + ) - commit = StrictAttributeDict({ - 'raw_id': 'raw_id', - 'message': 'message', - 'branch': 'branch', - }) - - comment = StrictAttributeDict({ - 'comment_id': 'comment_id', - 'text': 'text', - 'comment_type': 'comment_type', - 'f_path': 'f_path', - 'line_no': 'line_no', - 'last_version': 0, - }) + comment = StrictAttributeDict( + { + "comment_id": "comment_id", + "text": "text", + "comment_type": "comment_type", + "f_path": "f_path", + "line_no": "line_no", + "last_version": 0, + } + ) event = EventClass(repo=repo_stub, commit=commit, comment=comment) data = event.as_dict() - assert data['commit']['commit_id'] - assert data['comment']['comment_id'] + assert data["commit"]["commit_id"] + assert data["comment"]["comment_id"] diff --git a/rhodecode/tests/fixtures/fixture_pyramid.py b/rhodecode/tests/fixtures/fixture_pyramid.py index 26935325..6c536533 100644 --- a/rhodecode/tests/fixtures/fixture_pyramid.py +++ b/rhodecode/tests/fixtures/fixture_pyramid.py @@ -32,7 +32,17 @@ def vcsserver_factory(): Use this if you need a running vcsserver with a special configuration. """ - def factory(request, store_dir, overrides=(), config_file=None, port=None, log_file=None, workers="3", env=None, info_prefix=""): + def factory( + request, + store_dir, + overrides=(), + config_file=None, + port=None, + log_file=None, + workers="3", + env=None, + info_prefix="", + ): env = env or {"RC_NO_TEST_ENV": "1"} vcsserver_port = port if port is None: @@ -41,7 +51,7 @@ def vcsserver_factory(): overrides = list(overrides) overrides.append({"server:main": {"port": vcsserver_port}}) - if getattr(request, 'param', None): + if getattr(request, "param", None): config_overrides = [request.param] overrides.extend(config_overrides) @@ -71,7 +81,17 @@ def vcsserver_factory(): @pytest.fixture(scope="session") def rhodecode_factory(): - def factory(request, store_dir, overrides=(), config_file=None, port=None, log_file=None, workers="3", env=None, info_prefix=""): + def factory( + request, + store_dir, + overrides=(), + config_file=None, + port=None, + log_file=None, + workers="3", + env=None, + info_prefix="", + ): env = env or {"RC_NO_TEST_ENV": "1"} rhodecode_port = port if port is None: @@ -82,11 +102,10 @@ def rhodecode_factory(): overrides.append({"app:main": {"use_celery": "true"}}) overrides.append({"app:main": {"celery.task_always_eager": "false"}}) - if getattr(request, 'param', None): + if getattr(request, "param", None): config_overrides = [request.param] overrides.extend(config_overrides) - option_name = "rhodecode_config" override_option_name = None if not config_file: @@ -114,7 +133,17 @@ def rhodecode_factory(): @pytest.fixture(scope="session") def celery_factory(): - def factory(request, store_dir, overrides=(), config_file=None, port=None, log_file=None, workers="3", env=None, info_prefix=""): + def factory( + request, + store_dir, + overrides=(), + config_file=None, + port=None, + log_file=None, + workers="3", + env=None, + info_prefix="", + ): env = env or {"RC_NO_TEST_ENV": "1"} rhodecode_port = port @@ -123,7 +152,7 @@ def celery_factory(): overrides.append({"app:main": {"celery.task_always_eager": "false"}}) config_overrides = None - if getattr(request, 'param', None): + if getattr(request, "param", None): config_overrides = [request.param] overrides.extend(config_overrides) diff --git a/rhodecode/tests/fixtures/function_scoped_baseapp.py b/rhodecode/tests/fixtures/function_scoped_baseapp.py index b768258f..54282e22 100644 --- a/rhodecode/tests/fixtures/function_scoped_baseapp.py +++ b/rhodecode/tests/fixtures/function_scoped_baseapp.py @@ -21,17 +21,17 @@ from rhodecode.tests.utils import CustomTestApp from rhodecode.tests.fixtures.fixture_utils import plain_http_environ, plain_config_stub, plain_request_stub -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def request_stub(): return plain_request_stub() -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def config_stub(request, request_stub): return plain_config_stub(request, request_stub) -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def http_environ(): """ HTTP extra environ keys. @@ -43,7 +43,7 @@ def http_environ(): return plain_http_environ() -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def app(request, config_stub, http_environ, baseapp): app = CustomTestApp(baseapp, extra_environ=http_environ) if request.cls: diff --git a/rhodecode/tests/fixtures/module_scoped_baseapp.py b/rhodecode/tests/fixtures/module_scoped_baseapp.py index 3478e714..f75180ff 100644 --- a/rhodecode/tests/fixtures/module_scoped_baseapp.py +++ b/rhodecode/tests/fixtures/module_scoped_baseapp.py @@ -21,17 +21,17 @@ from rhodecode.tests.utils import CustomTestApp from rhodecode.tests.fixtures.fixture_utils import plain_http_environ, plain_config_stub, plain_request_stub -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def module_request_stub(): return plain_request_stub() -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def module_config_stub(request, module_request_stub): return plain_config_stub(request, module_request_stub) -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def module_http_environ(): """ HTTP extra environ keys. @@ -43,7 +43,7 @@ def module_http_environ(): return plain_http_environ() -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def module_app(request, module_config_stub, module_http_environ, baseapp): app = CustomTestApp(baseapp, extra_environ=module_http_environ) return app diff --git a/rhodecode/tests/fixtures/rcextensions_fixtures.py b/rhodecode/tests/fixtures/rcextensions_fixtures.py index c8879912..7af83b22 100644 --- a/rhodecode/tests/fixtures/rcextensions_fixtures.py +++ b/rhodecode/tests/fixtures/rcextensions_fixtures.py @@ -33,10 +33,11 @@ log = logging.getLogger(__name__) def store_rcextensions(destination, force=False): from rhodecode.config import rcextensions + package_path = rcextensions.__path__[0] # Note: rcextensions are looked up based on the path of the ini file - rcextensions_path = os.path.join(destination, 'rcextensions') + rcextensions_path = os.path.join(destination, "rcextensions") if force: shutil.rmtree(rcextensions_path, ignore_errors=True) @@ -50,19 +51,18 @@ def rcextensions(request, tmp_storage_location): """ # Note: rcextensions are looked up based on the path of the ini file - rcextensions_path = os.path.join(tmp_storage_location, 'rcextensions') + rcextensions_path = os.path.join(tmp_storage_location, "rcextensions") if os.path.exists(rcextensions_path): pytest.fail( - f"Path for rcextensions already exists, please clean up before " - f"test run this path: {rcextensions_path}") + f"Path for rcextensions already exists, please clean up before test run this path: {rcextensions_path}" + ) else: store_rcextensions(tmp_storage_location) -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def rcextensions_present(request): - class RcExtensionsPresent: def __init__(self, rcextensions_location): self.rcextensions_location = rcextensions_location @@ -77,12 +77,12 @@ def rcextensions_present(request): store_rcextensions(self.rcextensions_location) def cleanup(self): - shutil.rmtree(os.path.join(self.rcextensions_location, 'rcextensions')) + shutil.rmtree(os.path.join(self.rcextensions_location, "rcextensions")) return RcExtensionsPresent -@pytest.fixture(scope='function') +@pytest.fixture(scope="function") def rcextensions_modification(request): """ example usage:: @@ -108,7 +108,7 @@ def rcextensions_modification(request): self.rcextensions_location = rcextensions_location self.mods = mods if not isinstance(mods, list): - raise ValueError('mods must be a list of modifications') + raise ValueError("mods must be a list of modifications") def __enter__(self): if self.create_if_missing: @@ -127,10 +127,10 @@ def rcextensions_modification(request): def modification(self, hook_name, method_body): import ast - rcextensions_path = os.path.join(self.rcextensions_location, 'rcextensions') + rcextensions_path = os.path.join(self.rcextensions_location, "rcextensions") # Load the code from hooks.py - hooks_filename = os.path.join(rcextensions_path, 'hooks.py') + hooks_filename = os.path.join(rcextensions_path, "hooks.py") with open(hooks_filename, "r") as file: tree = ast.parse(file.read()) @@ -152,6 +152,8 @@ def rcextensions_modification(request): with open(hooks_filename, "w") as file: file.write(ast.unparse(tree)) # Requires Python 3.9+ - console_printer(f" [green]rcextensions[/green] Updated the body of '{hooks_filename}' function '{hook_name}'") + console_printer( + f" [green]rcextensions[/green] Updated the body of '{hooks_filename}' function '{hook_name}'" + ) return RcextensionsModification diff --git a/rhodecode/tests/functional/test_bad_request_data.py b/rhodecode/tests/functional/test_bad_request_data.py index bb459211..82983ca3 100644 --- a/rhodecode/tests/functional/test_bad_request_data.py +++ b/rhodecode/tests/functional/test_bad_request_data.py @@ -20,21 +20,16 @@ from rhodecode.tests import TestController class TestBadRequestData(TestController): - def test_bad_get_data(self): - self.app.get( - '/', params={'f\xfc': '\xfc%f6%22%20onmouseover%3dveA2(9352)%20'}, - status=200) + self.app.get("/", params={"f\xfc": "\xfc%f6%22%20onmouseover%3dveA2(9352)%20"}, status=200) def test_bad_url_data(self): - self.app.post( - '/f\xfc', - status=404) + self.app.post("/f\xfc", status=404) def test_bad_post_data(self, csrf_token, xhr_header): self.app.post( - '/_markup_preview', - params={'f\xfc': '\xfc%f6%22%20onmouseover%3dveA2(9352)%20', - 'csrf_token': csrf_token}, + "/_markup_preview", + params={"f\xfc": "\xfc%f6%22%20onmouseover%3dveA2(9352)%20", "csrf_token": csrf_token}, extra_environ=xhr_header, - status=200) + status=200, + ) diff --git a/rhodecode/tests/functional/test_delegated_admin.py b/rhodecode/tests/functional/test_delegated_admin.py index 12d79121..88e65e29 100644 --- a/rhodecode/tests/functional/test_delegated_admin.py +++ b/rhodecode/tests/functional/test_delegated_admin.py @@ -27,30 +27,26 @@ fixture = Fixture() class TestAdminDelegatedUser(TestController): - def test_regular_user_cannot_see_admin_interfaces(self, user_util, xhr_header): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") user_util.inherit_default_user_permissions(user.username, False) - self.log_user(user.username, 'qweqwe') + self.log_user(user.username, "qweqwe") # user doesn't have any access to resources so main admin page should 404 - self.app.get(route_path('admin_home'), status=404) + self.app.get(route_path("admin_home"), status=404) - response = self.app.get(route_path('repos_data'), - status=200, extra_environ=xhr_header) - assert response.json['data'] == [] + response = self.app.get(route_path("repos_data"), status=200, extra_environ=xhr_header) + assert response.json["data"] == [] - response = self.app.get(route_path('repo_groups_data'), - status=200, extra_environ=xhr_header) - assert response.json['data'] == [] + response = self.app.get(route_path("repo_groups_data"), status=200, extra_environ=xhr_header) + assert response.json["data"] == [] - response = self.app.get(route_path('user_groups_data'), - status=200, extra_environ=xhr_header) - assert response.json['data'] == [] + response = self.app.get(route_path("user_groups_data"), status=200, extra_environ=xhr_header) + assert response.json["data"] == [] def test_regular_user_can_see_admin_interfaces_if_owner(self, user_util, xhr_header): - user = user_util.create_user(password='qweqwe') + user = user_util.create_user(password="qweqwe") username = user.username repo = user_util.create_repo(owner=username) @@ -62,32 +58,28 @@ class TestAdminDelegatedUser(TestController): user_group = user_util.create_user_group(owner=username) user_group_name = user_group.users_group_name - self.log_user(username, 'qweqwe') + self.log_user(username, "qweqwe") - response = self.app.get(route_path('admin_home')) + response = self.app.get(route_path("admin_home")) assert_response = response.assert_response() - assert_response.element_contains('td.delegated-admin-repos', '1') - assert_response.element_contains('td.delegated-admin-repo-groups', '1') - assert_response.element_contains('td.delegated-admin-user-groups', '1') + assert_response.element_contains("td.delegated-admin-repos", "1") + assert_response.element_contains("td.delegated-admin-repo-groups", "1") + assert_response.element_contains("td.delegated-admin-user-groups", "1") # admin interfaces have visible elements - response = self.app.get(route_path('repos_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("repos_data"), extra_environ=xhr_header, status=200) response.mustcontain(''.format(repo_name)) - response = self.app.get(route_path('repo_groups_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("repo_groups_data"), extra_environ=xhr_header, status=200) response.mustcontain(''.format(repo_group_name)) - response = self.app.get(route_path('user_groups_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("user_groups_data"), extra_environ=xhr_header, status=200) response.mustcontain(''.format(user_group_name)) - def test_regular_user_can_see_admin_interfaces_if_admin_perm( - self, user_util, xhr_header): - user = user_util.create_user(password='qweqwe') + def test_regular_user_can_see_admin_interfaces_if_admin_perm(self, user_util, xhr_header): + user = user_util.create_user(password="qweqwe") username = user.username repo = user_util.create_repo() @@ -99,32 +91,26 @@ class TestAdminDelegatedUser(TestController): user_group = user_util.create_user_group() user_group_name = user_group.users_group_name - user_util.grant_user_permission_to_repo( - repo, user, 'repository.admin') - user_util.grant_user_permission_to_repo_group( - repo_group, user, 'group.admin') - user_util.grant_user_permission_to_user_group( - user_group, user, 'usergroup.admin') + user_util.grant_user_permission_to_repo(repo, user, "repository.admin") + user_util.grant_user_permission_to_repo_group(repo_group, user, "group.admin") + user_util.grant_user_permission_to_user_group(user_group, user, "usergroup.admin") - self.log_user(username, 'qweqwe') + self.log_user(username, "qweqwe") # check if in home view, such user doesn't see the "admin" menus - response = self.app.get(route_path('admin_home')) + response = self.app.get(route_path("admin_home")) assert_response = response.assert_response() - assert_response.element_contains('td.delegated-admin-repos', '1') - assert_response.element_contains('td.delegated-admin-repo-groups', '1') - assert_response.element_contains('td.delegated-admin-user-groups', '1') + assert_response.element_contains("td.delegated-admin-repos", "1") + assert_response.element_contains("td.delegated-admin-repo-groups", "1") + assert_response.element_contains("td.delegated-admin-user-groups", "1") # admin interfaces have visible elements - response = self.app.get(route_path('repos_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("repos_data"), extra_environ=xhr_header, status=200) response.mustcontain(''.format(repo_name)) - response = self.app.get(route_path('repo_groups_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("repo_groups_data"), extra_environ=xhr_header, status=200) response.mustcontain(''.format(repo_group_name)) - response = self.app.get(route_path('user_groups_data'), - extra_environ=xhr_header, status=200) + response = self.app.get(route_path("user_groups_data"), extra_environ=xhr_header, status=200) response.mustcontain(''.format(user_group_name)) diff --git a/rhodecode/tests/functional/test_sessions.py b/rhodecode/tests/functional/test_sessions.py index 5d0bda51..8d627e08 100644 --- a/rhodecode/tests/functional/test_sessions.py +++ b/rhodecode/tests/functional/test_sessions.py @@ -26,8 +26,7 @@ from rhodecode.tests.routes import route_path class TestSessionBehaviorOnPasswordChange(object): @pytest.fixture(autouse=True) def patch_password_changed(self, request): - password_changed_patcher = mock.patch( - 'rhodecode.lib.base.password_changed') + password_changed_patcher = mock.patch("rhodecode.lib.base.password_changed") self.password_changed_mock = password_changed_patcher.start() self.password_changed_mock.return_value = False @@ -35,36 +34,31 @@ class TestSessionBehaviorOnPasswordChange(object): def cleanup(): password_changed_patcher.stop() - def test_sessions_are_ok_when_password_is_not_changed( - self, app, autologin_user): - response = app.get(route_path('home')) + def test_sessions_are_ok_when_password_is_not_changed(self, app, autologin_user): + response = app.get(route_path("home")) assert_response = response.assert_response() - assert_response.element_contains( - '#quick_login_link .menu_link_user', TEST_USER_ADMIN_LOGIN) + assert_response.element_contains("#quick_login_link .menu_link_user", TEST_USER_ADMIN_LOGIN) session = response.get_session_from_response() - assert 'rhodecode_user' in session + assert "rhodecode_user" in session assert session.was_invalidated is False - def test_sessions_invalidated_when_password_is_changed( - self, app, autologin_user): - response = app.get(route_path('home'), status=200) + def test_sessions_invalidated_when_password_is_changed(self, app, autologin_user): + response = app.get(route_path("home"), status=200) session = response.get_session_from_response() # now mark as password change self.password_changed_mock.return_value = True # flushes session first - app.get(route_path('home')) + app.get(route_path("home")) # second call is now "different" with flushed empty session - response = app.get(route_path('home')) + response = app.get(route_path("home")) session = response.get_session_from_response() - assert 'rhodecode_user' not in session + assert "rhodecode_user" not in session assert_response = response.assert_response() - assert_response.element_contains('#quick_login_link .user', 'Sign in') - - + assert_response.element_contains("#quick_login_link .user", "Sign in") diff --git a/rhodecode/tests/integrations/conftest.py b/rhodecode/tests/integrations/conftest.py index 34ccf06d..bdb2bf7e 100644 --- a/rhodecode/tests/integrations/conftest.py +++ b/rhodecode/tests/integrations/conftest.py @@ -26,11 +26,11 @@ from rhodecode.tests.conftest import HTTPBIN_DOMAIN @pytest.fixture() def repo_push_event(backend, user_regular): commits = [ - {'message': 'ancestor commit fixes #15'}, - {'message': 'quick fixes'}, - {'message': 'change that fixes #41, #2'}, - {'message': 'this is because 5b23c3532 broke stuff'}, - {'message': 'last commit'}, + {"message": "ancestor commit fixes #15"}, + {"message": "quick fixes"}, + {"message": "change that fixes #41, #2"}, + {"message": "this is because 5b23c3532 broke stuff"}, + {"message": "last commit"}, ] r = backend.create_repo(commits) @@ -38,21 +38,21 @@ def repo_push_event(backend, user_regular): repo_name = backend.repo_name alias = backend.alias - scm_extras = AttributeDict({ - 'ip': '127.0.0.1', - 'username': user_regular.username, - 'user_id': user_regular.user_id, - 'action': '', - 'repository': repo_name, - 'scm': alias, - 'config': '', - 'repo_store': '', - 'server_url': HTTPBIN_DOMAIN, - 'make_lock': None, - 'locked_by': [None], - 'commit_ids': commit_ids, - }) + scm_extras = AttributeDict( + { + "ip": "127.0.0.1", + "username": user_regular.username, + "user_id": user_regular.user_id, + "action": "", + "repository": repo_name, + "scm": alias, + "config": "", + "repo_store": "", + "server_url": HTTPBIN_DOMAIN, + "make_lock": None, + "locked_by": [None], + "commit_ids": commit_ids, + } + ) - return events.RepoPushEvent(repo_name=repo_name, - pushed_commit_ids=commit_ids, - extras=scm_extras) + return events.RepoPushEvent(repo_name=repo_name, pushed_commit_ids=commit_ids, extras=scm_extras) diff --git a/rhodecode/tests/integrations/test_integration.py b/rhodecode/tests/integrations/test_integration.py index 43adb423..fc7f5538 100644 --- a/rhodecode/tests/integrations/test_integration.py +++ b/rhodecode/tests/integrations/test_integration.py @@ -35,7 +35,6 @@ class TestDeleteScopesDeletesIntegrations(object): assert integration is None def test_delete_repo_group_with_integration_deletes_integration(self, repogroup_integration_stub): - Session().delete(repogroup_integration_stub.repo_group) Session().commit() Session().expire_all() @@ -50,7 +49,7 @@ def counter(): global count val = count count += 1 - return f'{val}_{time.time()}' + return f"{val}_{time.time()}" @pytest.fixture() @@ -69,47 +68,51 @@ def integration_repos(request, StubIntegrationType, stub_integration_settings): """ fixture = Fixture() - parent_group_id = 'int_test_parent_group_{}'.format(counter()) + parent_group_id = "int_test_parent_group_{}".format(counter()) parent_group = fixture.create_repo_group(parent_group_id) - other_group_id = 'int_test_other_group_{}'.format(counter()) + other_group_id = "int_test_other_group_{}".format(counter()) other_group = fixture.create_repo_group(other_group_id) - child_group_id = ( - parent_group_id + '/' + 'int_test_child_group_{}'.format(counter())) + child_group_id = parent_group_id + "/" + "int_test_child_group_{}".format(counter()) child_group = fixture.create_repo_group(child_group_id) - parent_repo_id = 'int_test_parent_repo_{}'.format(counter()) + parent_repo_id = "int_test_parent_repo_{}".format(counter()) parent_repo = fixture.create_repo(parent_repo_id, repo_group=parent_group) - child_repo_id = 'int_test_child_repo_{}'.format(counter()) + child_repo_id = "int_test_child_repo_{}".format(counter()) child_repo = fixture.create_repo(child_repo_id, repo_group=child_group) - other_repo_id = 'int_test_other_repo_{}'.format(counter()) + other_repo_id = "int_test_other_repo_{}".format(counter()) other_repo = fixture.create_repo(other_repo_id, repo_group=other_group) - root_repo_id = 'int_test_repo_root_{}'.format(counter()) + root_repo_id = "int_test_repo_root_{}".format(counter()) root_repo = fixture.create_repo(root_repo_id) integrations = {} for name, repo, repo_group, child_repos_only in [ - ('global', None, None, None), - ('root_repos', None, None, True), - ('parent_repo', parent_repo, None, None), - ('child_repo', child_repo, None, None), - ('other_repo', other_repo, None, None), - ('root_repo', root_repo, None, None), - ('parent_group', None, parent_group, True), - ('parent_group_recursive', None, parent_group, False), - ('child_group', None, child_group, True), - ('child_group_recursive', None, child_group, False), - ('other_group', None, other_group, True), - ('other_group_recursive', None, other_group, False), - ]: + ("global", None, None, None), + ("root_repos", None, None, True), + ("parent_repo", parent_repo, None, None), + ("child_repo", child_repo, None, None), + ("other_repo", other_repo, None, None), + ("root_repo", root_repo, None, None), + ("parent_group", None, parent_group, True), + ("parent_group_recursive", None, parent_group, False), + ("child_group", None, child_group, True), + ("child_group_recursive", None, child_group, False), + ("other_group", None, other_group, True), + ("other_group_recursive", None, other_group, False), + ]: integrations[name] = IntegrationModel().create( - StubIntegrationType, settings=stub_integration_settings, - enabled=True, name='test %s integration' % name, - repo=repo, repo_group=repo_group, child_repos_only=child_repos_only) + StubIntegrationType, + settings=stub_integration_settings, + enabled=True, + name="test %s integration" % name, + repo=repo, + repo_group=repo_group, + child_repos_only=child_repos_only, + ) Session().commit() @@ -128,94 +131,85 @@ def integration_repos(request, StubIntegrationType, stub_integration_settings): request.addfinalizer(_cleanup) return { - 'integrations': integrations, - 'repos': { - 'root_repo': root_repo, - 'other_repo': other_repo, - 'parent_repo': parent_repo, - 'child_repo': child_repo, - } + "integrations": integrations, + "repos": { + "root_repo": root_repo, + "other_repo": other_repo, + "parent_repo": parent_repo, + "child_repo": child_repo, + }, } def test_enabled_integration_repo_scopes(integration_repos): - integrations = integration_repos['integrations'] - repos = integration_repos['repos'] + integrations = integration_repos["integrations"] + repos = integration_repos["repos"] - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['root_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["root_repo"])) assert triggered_integrations == [ - integrations['global'], - integrations['root_repos'], - integrations['root_repo'], + integrations["global"], + integrations["root_repos"], + integrations["root_repo"], ] - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['other_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["other_repo"])) assert triggered_integrations == [ - integrations['global'], - integrations['other_group'], - integrations['other_group_recursive'], - integrations['other_repo'], + integrations["global"], + integrations["other_group"], + integrations["other_group_recursive"], + integrations["other_repo"], ] - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['parent_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["parent_repo"])) assert triggered_integrations == [ - integrations['global'], - integrations['parent_group'], - integrations['parent_group_recursive'], - integrations['parent_repo'], + integrations["global"], + integrations["parent_group"], + integrations["parent_group_recursive"], + integrations["parent_repo"], ] - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['child_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["child_repo"])) assert triggered_integrations == [ - integrations['global'], - integrations['child_group'], - integrations['parent_group_recursive'], - integrations['child_group_recursive'], - integrations['child_repo'], + integrations["global"], + integrations["child_group"], + integrations["parent_group_recursive"], + integrations["child_group_recursive"], + integrations["child_repo"], ] def test_disabled_integration_repo_scopes(integration_repos): - integrations = integration_repos['integrations'] - repos = integration_repos['repos'] + integrations = integration_repos["integrations"] + repos = integration_repos["repos"] for integration in integrations.values(): integration.enabled = False Session().commit() - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['root_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["root_repo"])) assert triggered_integrations == [] - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['parent_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["parent_repo"])) assert triggered_integrations == [] - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['child_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["child_repo"])) assert triggered_integrations == [] - triggered_integrations = IntegrationModel().get_for_event( - events.RepoEvent(repos['other_repo'])) + triggered_integrations = IntegrationModel().get_for_event(events.RepoEvent(repos["other_repo"])) assert triggered_integrations == [] def test_enabled_non_repo_integrations(integration_repos): - integrations = integration_repos['integrations'] + integrations = integration_repos["integrations"] - triggered_integrations = IntegrationModel().get_for_event( - events.UserPreCreate({})) + triggered_integrations = IntegrationModel().get_for_event(events.UserPreCreate({})) - assert triggered_integrations == [integrations['global']] + assert triggered_integrations == [integrations["global"]] diff --git a/rhodecode/tests/integrations/test_slack.py b/rhodecode/tests/integrations/test_slack.py index 98129b62..42daedc6 100644 --- a/rhodecode/tests/integrations/test_slack.py +++ b/rhodecode/tests/integrations/test_slack.py @@ -61,19 +61,19 @@ def slack_settings(): return { "service": "mock://slackintegration", "events": [ - "pullrequest-create", - "repo-push", + "pullrequest-create", + "repo-push", ], "channel": "#testing", "icon_emoji": ":recycle:", - "username": "rhodecode-test" + "username": "rhodecode-test", } @pytest.fixture() def slack_integration(request, app, slack_settings): integration = Integration() - integration.name = 'test slack integration' + integration.name = "test slack integration" integration.enabled = True integration.integration_type = SlackIntegrationType.key integration.settings = slack_settings @@ -85,9 +85,9 @@ def slack_integration(request, app, slack_settings): @pytest.fixture() def slack_integration_empty(request, app, slack_settings): - slack_settings['events'] = [] + slack_settings["events"] = [] integration = Integration() - integration.name = 'test slack integration' + integration.name = "test slack integration" integration.enabled = True integration.integration_type = SlackIntegrationType.key integration.settings = slack_settings @@ -98,20 +98,18 @@ def slack_integration_empty(request, app, slack_settings): def test_slack_push(slack_integration, repo_push_event): - - with patch('rhodecode.integrations.types.slack.post_text_to_slack') as call: + with patch("rhodecode.integrations.types.slack.post_text_to_slack") as call: events.trigger(repo_push_event) - assert 'pushed to' in call.call_args[0][1].title + assert "pushed to" in call.call_args[0][1].title # specific commit was parsed and serialized - assert 'change that fixes #41' in call.call_args[0][1].text + assert "change that fixes #41" in call.call_args[0][1].text def test_slack_push_no_events(slack_integration_empty, repo_push_event): + assert Integration.get(slack_integration_empty.integration_id).settings["events"] == [] - assert Integration.get(slack_integration_empty.integration_id).settings['events'] == [] - - with patch('rhodecode.integrations.types.slack.post_text_to_slack') as call: + with patch("rhodecode.integrations.types.slack.post_text_to_slack") as call: events.trigger(repo_push_event) assert not call.call_args @@ -123,26 +121,29 @@ def test_slack_data_handler_wrong_event(): handler(events.RhodecodeEvent(), data) -@pytest.mark.parametrize("event_type, args", [ - ( - events.PullRequestCommentEvent, - (mock.MagicMock(name="pull-request"), mock.MagicMock(name="comment")), - ), - ( - events.PullRequestCommentEditEvent, - (mock.MagicMock(name="pull-request"), mock.MagicMock(name="comment")), - ), - ( - events.PullRequestReviewEvent, - (mock.MagicMock(name="pull-request"), mock.MagicMock(name="status")), - ), - ( - events.RepoPushEvent, - (GIT_REPO, mock.MagicMock(name="pushed_commit_ids"), mock.MagicMock(name="extras")), - ), - (events.PullRequestEvent, (mock.MagicMock(), )), - (events.RepoCreateEvent, (mock.MagicMock(), )), -]) +@pytest.mark.parametrize( + "event_type, args", + [ + ( + events.PullRequestCommentEvent, + (mock.MagicMock(name="pull-request"), mock.MagicMock(name="comment")), + ), + ( + events.PullRequestCommentEditEvent, + (mock.MagicMock(name="pull-request"), mock.MagicMock(name="comment")), + ), + ( + events.PullRequestReviewEvent, + (mock.MagicMock(name="pull-request"), mock.MagicMock(name="status")), + ), + ( + events.RepoPushEvent, + (GIT_REPO, mock.MagicMock(name="pushed_commit_ids"), mock.MagicMock(name="extras")), + ), + (events.PullRequestEvent, (mock.MagicMock(),)), + (events.RepoCreateEvent, (mock.MagicMock(),)), + ], +) def test_slack_data_handler(app, event_type: events.RhodecodeEvent, args, base_slack_data): handler = SlackDataHandler() handler(event_type(*args), base_slack_data) diff --git a/rhodecode/tests/integrations/test_webhook.py b/rhodecode/tests/integrations/test_webhook.py index fcc2e003..976decb8 100644 --- a/rhodecode/tests/integrations/test_webhook.py +++ b/rhodecode/tests/integrations/test_webhook.py @@ -29,18 +29,15 @@ from rhodecode.tests import GIT_REPO @pytest.fixture() def base_data(): return { - 'name': 'event', - 'repo': { - 'repo_name': 'foo', - 'repo_type': 'hg', - 'repo_id': '12', - 'url': 'http://repo.url/foo', - 'extra_fields': {}, - }, - 'actor': { - 'username': 'actor_name', - 'user_id': 1 + "name": "event", + "repo": { + "repo_name": "foo", + "repo_type": "hg", + "repo_id": "12", + "url": "http://repo.url/foo", + "extra_fields": {}, }, + "actor": {"username": "actor_name", "user_id": 1}, "pullrequest": { "url": "https://example.com/pr1", "pull_request_id": "1", @@ -57,24 +54,15 @@ def base_data(): "comment_line_no": "1", "comment_type": "note", }, - "commit": { - "commit_id": "efefef", - "commit_branch": "master", - "commit_message": "changed foo" - }, - "push": { - "branches": "", - "commits": [] - }, - + "commit": {"commit_id": "efefef", "commit_branch": "master", "commit_message": "changed foo"}, + "push": {"branches": "", "commits": []}, } def test_webhook_parse_url_invalid_event(): - template_url = 'http://server.com/${repo_name}/build' - handler = WebhookDataHandler( - template_url, {'exmaple-header': 'header-values'}) - event = events.RepoDeleteEvent('') + template_url = "http://server.com/${repo_name}/build" + handler = WebhookDataHandler(template_url, {"exmaple-header": "header-values"}) + event = events.RepoDeleteEvent("") with pytest.raises(ValueError) as err: handler(event, {}) @@ -82,114 +70,119 @@ def test_webhook_parse_url_invalid_event(): assert err == "event type `` has no handler defined" -@pytest.mark.parametrize('template,expected_urls', [ - ('http://server.com/${repo_name}/build', - ['http://server.com/foo/build']), - ('http://server.com/${repo_name}/${repo_type}', - ['http://server.com/foo/hg']), - ('http://${server}.com/${repo_name}/${repo_id}', - ['http://${server}.com/foo/12']), - ('http://server.com/${branch}/build', - ['http://server.com/${branch}/build']), -]) +@pytest.mark.parametrize( + "template,expected_urls", + [ + ("http://server.com/${repo_name}/build", ["http://server.com/foo/build"]), + ("http://server.com/${repo_name}/${repo_type}", ["http://server.com/foo/hg"]), + ("http://${server}.com/${repo_name}/${repo_id}", ["http://${server}.com/foo/12"]), + ("http://server.com/${branch}/build", ["http://server.com/${branch}/build"]), + ], +) def test_webook_parse_url_for_create_event(base_data, template, expected_urls): - headers = {'exmaple-header': 'header-values'} + headers = {"exmaple-header": "header-values"} handler = WebhookDataHandler(template, headers) - urls = handler(events.RepoCreateEvent(''), base_data) - assert urls == [ - (url, headers, base_data) for url in expected_urls] + urls = handler(events.RepoCreateEvent(""), base_data) + assert urls == [(url, headers, base_data) for url in expected_urls] -@pytest.mark.parametrize('template,expected_urls', [ - ('http://server.com/${repo_name}/${pull_request_id}', - ['http://server.com/foo/999']), - ('http://server.com/${repo_name}/${pull_request_url}', - ['http://server.com/foo/http%3A//pr-url.com']), - ('http://server.com/${repo_name}/${pull_request_url}/?TITLE=${pull_request_title}', - ['http://server.com/foo/http%3A//pr-url.com/?TITLE=example-pr-title%20Ticket%20%23123']), - ('http://server.com/${repo_name}/?SHADOW_URL=${pull_request_shadow_url}', - ['http://server.com/foo/?SHADOW_URL=http%3A//pr-url.com/repository']), -]) +@pytest.mark.parametrize( + "template,expected_urls", + [ + ("http://server.com/${repo_name}/${pull_request_id}", ["http://server.com/foo/999"]), + ("http://server.com/${repo_name}/${pull_request_url}", ["http://server.com/foo/http%3A//pr-url.com"]), + ( + "http://server.com/${repo_name}/${pull_request_url}/?TITLE=${pull_request_title}", + ["http://server.com/foo/http%3A//pr-url.com/?TITLE=example-pr-title%20Ticket%20%23123"], + ), + ( + "http://server.com/${repo_name}/?SHADOW_URL=${pull_request_shadow_url}", + ["http://server.com/foo/?SHADOW_URL=http%3A//pr-url.com/repository"], + ), + ], +) def test_webook_parse_url_for_pull_request_event(base_data, template, expected_urls): - - base_data['pullrequest'] = { - 'pull_request_id': 999, - 'url': 'http://pr-url.com', - 'title': 'example-pr-title Ticket #123', - 'commits_uid': 'abcdefg1234', - 'shadow_url': 'http://pr-url.com/repository' + base_data["pullrequest"] = { + "pull_request_id": 999, + "url": "http://pr-url.com", + "title": "example-pr-title Ticket #123", + "commits_uid": "abcdefg1234", + "shadow_url": "http://pr-url.com/repository", } - headers = {'exmaple-header': 'header-values'} + headers = {"exmaple-header": "header-values"} handler = WebhookDataHandler(template, headers) - urls = handler(events.PullRequestCreateEvent( - AttributeDict({'target_repo': 'foo'})), base_data) - assert urls == [ - (url, headers, base_data) for url in expected_urls] + urls = handler(events.PullRequestCreateEvent(AttributeDict({"target_repo": "foo"})), base_data) + assert urls == [(url, headers, base_data) for url in expected_urls] -@pytest.mark.parametrize('template,expected_urls', [ - ('http://server.com/${branch}/build', - ['http://server.com/stable/build', - 'http://server.com/dev/build']), - ('http://server.com/${branch}/${commit_id}', - ['http://server.com/stable/stable-xxx', - 'http://server.com/stable/stable-yyy', - 'http://server.com/dev/dev-xxx', - 'http://server.com/dev/dev-yyy']), - ('http://server.com/${branch_head}', - ['http://server.com/stable-yyy', - 'http://server.com/dev-yyy']), - ('http://server.com/${commit_id}', - ['http://server.com/stable-xxx', - 'http://server.com/stable-yyy', - 'http://server.com/dev-xxx', - 'http://server.com/dev-yyy']), -]) -def test_webook_parse_url_for_push_event( - baseapp, repo_push_event, base_data, template, expected_urls): - base_data['push'] = { - 'branches': [{'name': 'stable'}, {'name': 'dev'}], - 'commits': [{'branch': 'stable', 'raw_id': 'stable-xxx'}, - {'branch': 'stable', 'raw_id': 'stable-yyy'}, - {'branch': 'dev', 'raw_id': 'dev-xxx'}, - {'branch': 'dev', 'raw_id': 'dev-yyy'}] +@pytest.mark.parametrize( + "template,expected_urls", + [ + ("http://server.com/${branch}/build", ["http://server.com/stable/build", "http://server.com/dev/build"]), + ( + "http://server.com/${branch}/${commit_id}", + [ + "http://server.com/stable/stable-xxx", + "http://server.com/stable/stable-yyy", + "http://server.com/dev/dev-xxx", + "http://server.com/dev/dev-yyy", + ], + ), + ("http://server.com/${branch_head}", ["http://server.com/stable-yyy", "http://server.com/dev-yyy"]), + ( + "http://server.com/${commit_id}", + [ + "http://server.com/stable-xxx", + "http://server.com/stable-yyy", + "http://server.com/dev-xxx", + "http://server.com/dev-yyy", + ], + ), + ], +) +def test_webook_parse_url_for_push_event(baseapp, repo_push_event, base_data, template, expected_urls): + base_data["push"] = { + "branches": [{"name": "stable"}, {"name": "dev"}], + "commits": [ + {"branch": "stable", "raw_id": "stable-xxx"}, + {"branch": "stable", "raw_id": "stable-yyy"}, + {"branch": "dev", "raw_id": "dev-xxx"}, + {"branch": "dev", "raw_id": "dev-yyy"}, + ], } - headers = {'exmaple-header': 'header-values'} + headers = {"exmaple-header": "header-values"} handler = WebhookDataHandler(template, headers) urls = handler(repo_push_event, base_data) - assert urls == [ - (url, headers, base_data) for url in expected_urls] + assert urls == [(url, headers, base_data) for url in expected_urls] -@pytest.mark.parametrize("event_type, args", [ - ( - events.RepoPushEvent, - (GIT_REPO, mock.MagicMock(name="pushed_commit_ids"), mock.MagicMock(name="extras")), - ), - ( - events.RepoCreateEvent, - (GIT_REPO,), - ), - ( - events.RepoCommitCommentEvent, - (GIT_REPO, mock.MagicMock(name="commit"), mock.MagicMock(name="comment")), - ), - ( - events.RepoCommitCommentEditEvent, - (GIT_REPO, mock.MagicMock(name="commit"), mock.MagicMock(name="comment")), - ), - ( - events.PullRequestEvent, - (mock.MagicMock(), ), - ), -]) +@pytest.mark.parametrize( + "event_type, args", + [ + ( + events.RepoPushEvent, + (GIT_REPO, mock.MagicMock(name="pushed_commit_ids"), mock.MagicMock(name="extras")), + ), + ( + events.RepoCreateEvent, + (GIT_REPO,), + ), + ( + events.RepoCommitCommentEvent, + (GIT_REPO, mock.MagicMock(name="commit"), mock.MagicMock(name="comment")), + ), + ( + events.RepoCommitCommentEditEvent, + (GIT_REPO, mock.MagicMock(name="commit"), mock.MagicMock(name="comment")), + ), + ( + events.PullRequestEvent, + (mock.MagicMock(),), + ), + ], +) def test_webhook_data_handler(app, event_type: events.RhodecodeEvent, args, base_data): handler = WebhookDataHandler( - template_url='http://server.com/${branch}/${commit_id}', - headers={'exmaple-header': 'header-values'} + template_url="http://server.com/${branch}/${commit_id}", headers={"exmaple-header": "header-values"} ) handler(event_type(*args), base_data) - - - - diff --git a/rhodecode/tests/lib/auth_modules/test_auth_modules.py b/rhodecode/tests/lib/auth_modules/test_auth_modules.py index cd485f56..9b27c3f3 100644 --- a/rhodecode/tests/lib/auth_modules/test_auth_modules.py +++ b/rhodecode/tests/lib/auth_modules/test_auth_modules.py @@ -26,51 +26,49 @@ from rhodecode.model import db class RcTestAuthPlugin(RhodeCodeAuthPluginBase): - def name(self): - return 'stub_auth' + return "stub_auth" def test_authenticate_returns_from_auth(stub_auth_data): - plugin = RcTestAuthPlugin('stub_id') - with mock.patch.object(plugin, 'auth') as auth_mock: + plugin = RcTestAuthPlugin("stub_id") + with mock.patch.object(plugin, "auth") as auth_mock: auth_mock.return_value = stub_auth_data - result = plugin._authenticate(mock.Mock(), 'test', 'password', {}) + result = plugin._authenticate(mock.Mock(), "test", "password", {}) assert stub_auth_data == result def test_authenticate_returns_empty_auth_data(): auth_data = {} - plugin = RcTestAuthPlugin('stub_id') - with mock.patch.object(plugin, 'auth') as auth_mock: + plugin = RcTestAuthPlugin("stub_id") + with mock.patch.object(plugin, "auth") as auth_mock: auth_mock.return_value = auth_data - result = plugin._authenticate(mock.Mock(), 'test', 'password', {}) + result = plugin._authenticate(mock.Mock(), "test", "password", {}) assert auth_data == result def test_authenticate_skips_hash_migration_if_mismatch(stub_auth_data): - stub_auth_data['_hash_migrate'] = 'new-hash' - plugin = RcTestAuthPlugin('stub_id') - with mock.patch.object(plugin, 'auth') as auth_mock: + stub_auth_data["_hash_migrate"] = "new-hash" + plugin = RcTestAuthPlugin("stub_id") + with mock.patch.object(plugin, "auth") as auth_mock: auth_mock.return_value = stub_auth_data - result = plugin._authenticate(mock.Mock(), 'test', 'password', {}) + result = plugin._authenticate(mock.Mock(), "test", "password", {}) - user = db.User.get_by_username(stub_auth_data['username']) - assert user.password != 'new-hash' + user = db.User.get_by_username(stub_auth_data["username"]) + assert user.password != "new-hash" assert result == stub_auth_data def test_authenticate_migrates_to_new_hash(stub_auth_data): - new_password = b'new-password' + new_password = b"new-password" new_hash = _RhodeCodeCryptoBCrypt().hash_create(new_password) - stub_auth_data['_hash_migrate'] = new_hash - plugin = RcTestAuthPlugin('stub_id') - with mock.patch.object(plugin, 'auth') as auth_mock: + stub_auth_data["_hash_migrate"] = new_hash + plugin = RcTestAuthPlugin("stub_id") + with mock.patch.object(plugin, "auth") as auth_mock: auth_mock.return_value = stub_auth_data - result = plugin._authenticate( - mock.Mock(), stub_auth_data['username'], new_password, {}) + result = plugin._authenticate(mock.Mock(), stub_auth_data["username"], new_password, {}) - user = db.User.get_by_username(stub_auth_data['username']) + user = db.User.get_by_username(stub_auth_data["username"]) assert user.password == new_hash assert result == stub_auth_data @@ -79,17 +77,17 @@ def test_authenticate_migrates_to_new_hash(stub_auth_data): def stub_auth_data(user_util): user = user_util.create_user() data = { - 'username': user.username, - 'password': 'password', - 'email': 'test@example.org', - 'firstname': 'John', - 'lastname': 'Smith', - 'groups': [], - 'active': True, - 'admin': False, - 'extern_name': 'test', - 'extern_type': 'ldap', - 'active_from_extern': True + "username": user.username, + "password": "password", + "email": "test@example.org", + "firstname": "John", + "lastname": "Smith", + "groups": [], + "active": True, + "admin": False, + "extern_name": "test", + "extern_type": "ldap", + "active_from_extern": True, } return data @@ -98,20 +96,20 @@ class TestRhodeCodeAuthPlugin(object): def setup_method(self, method): self.finalizers = [] self.user = mock.Mock() - self.user.username = 'test' - self.user.password = 'old-password' + self.user.username = "test" + self.user.password = "old-password" self.fake_auth = { - 'username': 'test', - 'password': 'test', - 'email': 'test@example.org', - 'firstname': 'John', - 'lastname': 'Smith', - 'groups': [], - 'active': True, - 'admin': False, - 'extern_name': 'test', - 'extern_type': 'ldap', - 'active_from_extern': True + "username": "test", + "password": "test", + "email": "test@example.org", + "firstname": "John", + "lastname": "Smith", + "groups": [], + "active": True, + "admin": False, + "extern_name": "test", + "extern_type": "ldap", + "active_from_extern": True, } def teardown_method(self, method): @@ -122,42 +120,40 @@ class TestRhodeCodeAuthPlugin(object): def test_fake_password_is_created_for_the_new_user(self): self._patch() - auth_plugin = RhodeCodeAuthPlugin('stub_id') - auth_plugin._authenticate(self.user, 'test', 'test', []) + auth_plugin = RhodeCodeAuthPlugin("stub_id") + auth_plugin._authenticate(self.user, "test", "test", []) self.password_generator_mock.assert_called_once_with(length=16) create_user_kwargs = self.create_user_mock.call_args[1] - assert create_user_kwargs['password'] == 'new-password' + assert create_user_kwargs["password"] == "new-password" def test_fake_password_is_not_created_for_the_existing_user(self): self._patch() self.get_user_mock.return_value = self.user - auth_plugin = RhodeCodeAuthPlugin('stub_id') - auth_plugin._authenticate(self.user, 'test', 'test', []) + auth_plugin = RhodeCodeAuthPlugin("stub_id") + auth_plugin._authenticate(self.user, "test", "test", []) assert self.password_generator_mock.called is False create_user_kwargs = self.create_user_mock.call_args[1] - assert create_user_kwargs['password'] == self.user.password + assert create_user_kwargs["password"] == self.user.password def _patch(self): - get_user_patch = mock.patch('rhodecode.model.db.User.get_by_username') + get_user_patch = mock.patch("rhodecode.model.db.User.get_by_username") self.get_user_mock = get_user_patch.start() self.get_user_mock.return_value = None self.finalizers.append(get_user_patch.stop) - create_user_patch = mock.patch( - 'rhodecode.model.user.UserModel.create_or_update') + create_user_patch = mock.patch("rhodecode.model.user.UserModel.create_or_update") self.create_user_mock = create_user_patch.start() self.create_user_mock.return_value = None self.finalizers.append(create_user_patch.stop) - auth_patch = mock.patch.object(RhodeCodeAuthPlugin, 'auth') + auth_patch = mock.patch.object(RhodeCodeAuthPlugin, "auth") self.auth_mock = auth_patch.start() self.auth_mock.return_value = self.fake_auth self.finalizers.append(auth_patch.stop) - password_generator_patch = mock.patch( - 'rhodecode.lib.auth.PasswordGenerator.gen_password') + password_generator_patch = mock.patch("rhodecode.lib.auth.PasswordGenerator.gen_password") self.password_generator_mock = password_generator_patch.start() - self.password_generator_mock.return_value = 'new-password' + self.password_generator_mock.return_value = "new-password" self.finalizers.append(password_generator_patch.stop) diff --git a/rhodecode/tests/lib/middleware/mock_scm_app.py b/rhodecode/tests/lib/middleware/mock_scm_app.py index b6ec21c0..6242287a 100644 --- a/rhodecode/tests/lib/middleware/mock_scm_app.py +++ b/rhodecode/tests/lib/middleware/mock_scm_app.py @@ -22,6 +22,7 @@ Provides a mock implementation of the scm_app module. It resembles the same API as :mod:`rhodecode.lib.middleware.utils.scm_app` for testing purposes. """ + import mock diff --git a/rhodecode/tests/lib/middleware/test_appenlight.py b/rhodecode/tests/lib/middleware/test_appenlight.py index c08d5405..2187b7f7 100644 --- a/rhodecode/tests/lib/middleware/test_appenlight.py +++ b/rhodecode/tests/lib/middleware/test_appenlight.py @@ -21,16 +21,18 @@ import pytest from rhodecode.lib.middleware import appenlight -@pytest.mark.parametrize('environ_stub', [ - # Recent clients provide an empty dict inside of the request environment - {'appenlight.extra': {}}, - # Case of old client or no client being active, it still should not break - {}, - {'other.key': 'other data'}, -]) +@pytest.mark.parametrize( + "environ_stub", + [ + # Recent clients provide an empty dict inside of the request environment + {"appenlight.extra": {}}, + # Case of old client or no client being active, it still should not break + {}, + {"other.key": "other data"}, + ], +) def test_track_extra_information(environ_stub): expected = environ_stub.copy() - expected.update({'appenlight.extra': {'test_section': 'test_value'}}) - appenlight.track_extra_information( - environ_stub, 'test_section', 'test_value') + expected.update({"appenlight.extra": {"test_section": "test_value"}}) + appenlight.track_extra_information(environ_stub, "test_section", "test_value") assert environ_stub == expected diff --git a/rhodecode/tests/lib/middleware/test_simplegit.py b/rhodecode/tests/lib/middleware/test_simplegit.py index 7c93ee91..74c1fe55 100644 --- a/rhodecode/tests/lib/middleware/test_simplegit.py +++ b/rhodecode/tests/lib/middleware/test_simplegit.py @@ -29,109 +29,105 @@ def get_environ(url, request_method): """Construct a minimum WSGI environ based on the URL.""" parsed_url = urllib.parse.urlparse(url) environ = { - 'PATH_INFO': parsed_url.path, - 'QUERY_STRING': parsed_url.query, - 'REQUEST_METHOD': request_method, + "PATH_INFO": parsed_url.path, + "QUERY_STRING": parsed_url.query, + "REQUEST_METHOD": request_method, } return environ @pytest.mark.parametrize( - 'url, expected_action, request_method', + "url, expected_action, request_method", [ - ('/foo/bar/info/refs?service=git-upload-pack', 'pull', 'GET'), - ('/foo/bar/info/refs?service=git-receive-pack', 'push', 'GET'), - ('/foo/bar/git-upload-pack', 'pull', 'GET'), - ('/foo/bar/git-receive-pack', 'push', 'GET'), + ("/foo/bar/info/refs?service=git-upload-pack", "pull", "GET"), + ("/foo/bar/info/refs?service=git-receive-pack", "push", "GET"), + ("/foo/bar/git-upload-pack", "pull", "GET"), + ("/foo/bar/git-receive-pack", "push", "GET"), # Edge case: missing data for info/refs - ('/foo/info/refs?service=', 'pull', 'GET'), - ('/foo/info/refs', 'pull', 'GET'), + ("/foo/info/refs?service=", "pull", "GET"), + ("/foo/info/refs", "pull", "GET"), # Edge case: git command comes with service argument - ('/foo/git-upload-pack?service=git-receive-pack', 'pull', 'GET'), - ('/foo/git-receive-pack?service=git-upload-pack', 'push', 'GET'), + ("/foo/git-upload-pack?service=git-receive-pack", "pull", "GET"), + ("/foo/git-receive-pack?service=git-upload-pack", "push", "GET"), # Edge case: repo name conflicts with git commands - ('/git-receive-pack/git-upload-pack', 'pull', 'GET'), - ('/git-receive-pack/git-receive-pack', 'push', 'GET'), - ('/git-upload-pack/git-upload-pack', 'pull', 'GET'), - ('/git-upload-pack/git-receive-pack', 'push', 'GET'), - ('/foo/git-receive-pack', 'push', 'GET'), + ("/git-receive-pack/git-upload-pack", "pull", "GET"), + ("/git-receive-pack/git-receive-pack", "push", "GET"), + ("/git-upload-pack/git-upload-pack", "pull", "GET"), + ("/git-upload-pack/git-receive-pack", "push", "GET"), + ("/foo/git-receive-pack", "push", "GET"), # Edge case: not a smart protocol url - ('/foo/bar', 'pull', 'GET'), + ("/foo/bar", "pull", "GET"), # GIT LFS cases, batch - ('/foo/bar/info/lfs/objects/batch', 'push', 'GET'), - ('/foo/bar/info/lfs/objects/batch', 'pull', 'POST'), + ("/foo/bar/info/lfs/objects/batch", "push", "GET"), + ("/foo/bar/info/lfs/objects/batch", "pull", "POST"), # GIT LFS oid, dl/upl - ('/foo/bar/info/lfs/abcdeabcde', 'pull', 'GET'), - ('/foo/bar/info/lfs/abcdeabcde', 'push', 'PUT'), - ('/foo/bar/info/lfs/abcdeabcde', 'push', 'POST'), + ("/foo/bar/info/lfs/abcdeabcde", "pull", "GET"), + ("/foo/bar/info/lfs/abcdeabcde", "push", "PUT"), + ("/foo/bar/info/lfs/abcdeabcde", "push", "POST"), # Edge case: repo name conflicts with git commands - ('/info/lfs/info/lfs/objects/batch', 'push', 'GET'), - ('/info/lfs/info/lfs/objects/batch', 'pull', 'POST'), - - ]) + ("/info/lfs/info/lfs/objects/batch", "push", "GET"), + ("/info/lfs/info/lfs/objects/batch", "pull", "POST"), + ], +) def test_get_action(url, expected_action, request_method, baseapp, request_stub): - app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''}, - registry=request_stub.registry) + app = simplegit.SimpleGit(config={"auth_ret_code": "", "base_path": ""}, registry=request_stub.registry) assert expected_action == app._get_action(get_environ(url, request_method)) @pytest.mark.parametrize( - 'url, expected_repo_name, request_method', + "url, expected_repo_name, request_method", [ - ('/foo/info/refs?service=git-upload-pack', 'foo', 'GET'), - ('/foo/bar/info/refs?service=git-receive-pack', 'foo/bar', 'GET'), - ('/foo/git-upload-pack', 'foo', 'GET'), - ('/foo/git-receive-pack', 'foo', 'GET'), - ('/foo/bar/git-upload-pack', 'foo/bar', 'GET'), - ('/foo/bar/git-receive-pack', 'foo/bar', 'GET'), - + ("/foo/info/refs?service=git-upload-pack", "foo", "GET"), + ("/foo/bar/info/refs?service=git-receive-pack", "foo/bar", "GET"), + ("/foo/git-upload-pack", "foo", "GET"), + ("/foo/git-receive-pack", "foo", "GET"), + ("/foo/bar/git-upload-pack", "foo/bar", "GET"), + ("/foo/bar/git-receive-pack", "foo/bar", "GET"), # GIT LFS cases, batch - ('/foo/bar/info/lfs/objects/batch', 'foo/bar', 'GET'), - ('/example-git/info/lfs/objects/batch', 'example-git', 'POST'), + ("/foo/bar/info/lfs/objects/batch", "foo/bar", "GET"), + ("/example-git/info/lfs/objects/batch", "example-git", "POST"), # GIT LFS oid, dl/upl - ('/foo/info/lfs/abcdeabcde', 'foo', 'GET'), - ('/foo/bar/info/lfs/abcdeabcde', 'foo/bar', 'PUT'), - ('/my-git-repo/info/lfs/abcdeabcde', 'my-git-repo', 'POST'), + ("/foo/info/lfs/abcdeabcde", "foo", "GET"), + ("/foo/bar/info/lfs/abcdeabcde", "foo/bar", "PUT"), + ("/my-git-repo/info/lfs/abcdeabcde", "my-git-repo", "POST"), # Edge case: repo name conflicts with git commands - ('/info/lfs/info/lfs/objects/batch', 'info/lfs', 'GET'), - ('/info/lfs/info/lfs/objects/batch', 'info/lfs', 'POST'), - - ]) + ("/info/lfs/info/lfs/objects/batch", "info/lfs", "GET"), + ("/info/lfs/info/lfs/objects/batch", "info/lfs", "POST"), + ], +) def test_get_repository_name(url, expected_repo_name, request_method, baseapp, request_stub): - app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''}, - registry=request_stub.registry) - assert expected_repo_name == app._get_repository_name( - get_environ(url, request_method)) + app = simplegit.SimpleGit(config={"auth_ret_code": "", "base_path": ""}, registry=request_stub.registry) + assert expected_repo_name == app._get_repository_name(get_environ(url, request_method)) def test_get_config(user_util, baseapp, request_stub): - repo = user_util.create_repo(repo_type='git') - app = simplegit.SimpleGit(config={'auth_ret_code': '', 'base_path': ''}, - registry=request_stub.registry) - extras = {'foo': 'FOO', 'bar': 'BAR'} + repo = user_util.create_repo(repo_type="git") + app = simplegit.SimpleGit(config={"auth_ret_code": "", "base_path": ""}, registry=request_stub.registry) + extras = {"foo": "FOO", "bar": "BAR"} # We copy the extras as the method below will change the contents. git_config = app._create_config(dict(extras), repo_name=repo.repo_name) expected_config = dict(extras) - expected_config.update({ - 'git_update_server_info': False, - 'git_lfs_enabled': False, - 'git_lfs_store_path': git_config['git_lfs_store_path'], - 'git_lfs_http_scheme': 'http' - }) + expected_config.update( + { + "git_update_server_info": False, + "git_lfs_enabled": False, + "git_lfs_store_path": git_config["git_lfs_store_path"], + "git_lfs_http_scheme": "http", + } + ) assert git_config == expected_config def test_create_wsgi_app_uses_scm_app_from_simplevcs(baseapp, request_stub): config = { - 'auth_ret_code': '', - 'base_path': '', - 'vcs.scm_app_implementation': - 'rhodecode.tests.lib.middleware.mock_scm_app', + "auth_ret_code": "", + "base_path": "", + "vcs.scm_app_implementation": "rhodecode.tests.lib.middleware.mock_scm_app", } app = simplegit.SimpleGit(config=config, registry=request_stub.registry) - wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {}) + wsgi_app = app._create_wsgi_app("/tmp/test", "test_repo", {}) assert wsgi_app is mock_scm_app.mock_git_wsgi diff --git a/rhodecode/tests/lib/middleware/test_simplehg.py b/rhodecode/tests/lib/middleware/test_simplehg.py index 3c8ef08f..2465cb94 100644 --- a/rhodecode/tests/lib/middleware/test_simplehg.py +++ b/rhodecode/tests/lib/middleware/test_simplehg.py @@ -31,54 +31,51 @@ def get_environ(url): """Construct a minimum WSGI environ based on the URL.""" parsed_url = urllib.parse.urlparse(url) environ = { - 'PATH_INFO': parsed_url.path, - 'QUERY_STRING': parsed_url.query, + "PATH_INFO": parsed_url.path, + "QUERY_STRING": parsed_url.query, } return environ @pytest.mark.parametrize( - 'url, expected_action', + "url, expected_action", [ - ('/foo/bar?cmd=unbundle&key=tip', 'push'), - ('/foo/bar?cmd=pushkey&key=tip', 'push'), - ('/foo/bar?cmd=listkeys&key=tip', 'pull'), - ('/foo/bar?cmd=changegroup&key=tip', 'pull'), - ('/foo/bar?cmd=hello', 'pull'), - ('/foo/bar?cmd=batch', 'push'), - ('/foo/bar?cmd=putlfile', 'push'), + ("/foo/bar?cmd=unbundle&key=tip", "push"), + ("/foo/bar?cmd=pushkey&key=tip", "push"), + ("/foo/bar?cmd=listkeys&key=tip", "pull"), + ("/foo/bar?cmd=changegroup&key=tip", "pull"), + ("/foo/bar?cmd=hello", "pull"), + ("/foo/bar?cmd=batch", "push"), + ("/foo/bar?cmd=putlfile", "push"), # Edge case: unknown argument: assume push - ('/foo/bar?cmd=unknown&key=tip', 'push'), - ('/foo/bar?cmd=&key=tip', 'push'), + ("/foo/bar?cmd=unknown&key=tip", "push"), + ("/foo/bar?cmd=&key=tip", "push"), # Edge case: not cmd argument - ('/foo/bar?key=tip', 'push'), - ]) + ("/foo/bar?key=tip", "push"), + ], +) def test_get_action(url, expected_action, request_stub): - app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''}, - registry=request_stub.registry) + app = simplehg.SimpleHg(config={"auth_ret_code": "", "base_path": ""}, registry=request_stub.registry) assert expected_action == app._get_action(get_environ(url)) @pytest.mark.parametrize( - 'environ, expected_xargs, expected_batch', + "environ, expected_xargs, expected_batch", [ - ({}, - [''], ['push']), - - ({'HTTP_X_HGARG_1': ''}, - [''], ['push']), - - ({'HTTP_X_HGARG_1': 'cmds=listkeys+namespace%3Dphases'}, - ['listkeys namespace=phases'], ['pull']), - - ({'HTTP_X_HGARG_1': 'cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'}, - ['pushkey namespace=bookmarks,key=bm,old=,new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b'], ['push']), - - ({'HTTP_X_HGARG_1': 'namespace=phases'}, - ['namespace=phases'], ['push']), - - ]) + ({}, [""], ["push"]), + ({"HTTP_X_HGARG_1": ""}, [""], ["push"]), + ({"HTTP_X_HGARG_1": "cmds=listkeys+namespace%3Dphases"}, ["listkeys namespace=phases"], ["pull"]), + ( + { + "HTTP_X_HGARG_1": "cmds=pushkey+namespace%3Dbookmarks%2Ckey%3Dbm%2Cold%3D%2Cnew%3Dcb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b" + }, + ["pushkey namespace=bookmarks,key=bm,old=,new=cb9a9f314b8b07ba71012fcdbc544b5a4d82ff5b"], + ["push"], + ), + ({"HTTP_X_HGARG_1": "namespace=phases"}, ["namespace=phases"], ["push"]), + ], +) def test_xarg_and_batch_commands(environ, expected_xargs, expected_batch): app = simplehg.SimpleHg @@ -89,57 +86,53 @@ def test_xarg_and_batch_commands(environ, expected_xargs, expected_batch): @pytest.mark.parametrize( - 'url, expected_repo_name', + "url, expected_repo_name", [ - ('/foo?cmd=unbundle&key=tip', 'foo'), - ('/foo/bar?cmd=pushkey&key=tip', 'foo/bar'), - ('/foo/bar/baz?cmd=listkeys&key=tip', 'foo/bar/baz'), + ("/foo?cmd=unbundle&key=tip", "foo"), + ("/foo/bar?cmd=pushkey&key=tip", "foo/bar"), + ("/foo/bar/baz?cmd=listkeys&key=tip", "foo/bar/baz"), # Repos with trailing slashes. - ('/foo/?cmd=unbundle&key=tip', 'foo'), - ('/foo/bar/?cmd=pushkey&key=tip', 'foo/bar'), - ('/foo/bar/baz/?cmd=listkeys&key=tip', 'foo/bar/baz'), - ]) + ("/foo/?cmd=unbundle&key=tip", "foo"), + ("/foo/bar/?cmd=pushkey&key=tip", "foo/bar"), + ("/foo/bar/baz/?cmd=listkeys&key=tip", "foo/bar/baz"), + ], +) def test_get_repository_name(url, expected_repo_name, request_stub): - app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''}, - registry=request_stub.registry) + app = simplehg.SimpleHg(config={"auth_ret_code": "", "base_path": ""}, registry=request_stub.registry) assert expected_repo_name == app._get_repository_name(get_environ(url)) def test_get_config(user_util, baseapp, request_stub): - repo = user_util.create_repo(repo_type='git') - app = simplehg.SimpleHg(config={'auth_ret_code': '', 'base_path': ''}, - registry=request_stub.registry) - extras = [('foo', 'FOO', 'bar', 'BAR')] + repo = user_util.create_repo(repo_type="git") + app = simplehg.SimpleHg(config={"auth_ret_code": "", "base_path": ""}, registry=request_stub.registry) + extras = [("foo", "FOO", "bar", "BAR")] hg_config = app._create_config(extras, repo_name=repo.repo_name) config = simplehg.utils.make_db_config(repo=repo.repo_name) - config.set('rhodecode', 'RC_SCM_DATA', json.dumps(extras)) + config.set("rhodecode", "RC_SCM_DATA", json.dumps(extras)) hg_config_org = config expected_config = [ - ('vcs_svn_tag', 'ff89f8c714d135d865f44b90e5413b88de19a55f', '/tags/*'), - ('web', 'allow_push', '*'), - ('web', 'allow_archive', 'gz zip bz2'), - ('web', 'baseurl', '/'), - + ("vcs_svn_tag", "ff89f8c714d135d865f44b90e5413b88de19a55f", "/tags/*"), + ("web", "allow_push", "*"), + ("web", "allow_archive", "gz zip bz2"), + ("web", "baseurl", "/"), # largefiles data... - ('vcs_git_lfs', 'store_location', hg_config_org.get('vcs_git_lfs', 'store_location')), - ('largefiles', 'usercache', hg_config_org.get('largefiles', 'usercache')), - - ('vcs_svn_branch', '9aac1a38c3b8a0cdc4ae0f960a5f83332bc4fa5e', '/branches/*'), - ('vcs_svn_branch', 'c7e6a611c87da06529fd0dd733308481d67c71a8', '/trunk'), - - ('hooks', 'preoutgoing.pre_pull', 'python:vcsserver.hooks.pre_pull'), - ('hooks', 'prechangegroup.pre_push', 'python:vcsserver.hooks.pre_push'), - ('hooks', 'outgoing.pull_logger', 'python:vcsserver.hooks.log_pull_action'), - ('hooks', 'pretxnchangegroup.pre_push', 'python:vcsserver.hooks.pre_push'), - ('hooks', 'changegroup.push_logger', 'python:vcsserver.hooks.log_push_action'), - ('hooks', 'changegroup.repo_size', 'python:vcsserver.hooks.repo_size'), - ('phases', 'publish', 'True'), - ('extensions', 'largefiles', ''), - ('paths', '/', hg_config_org.get('paths', '/')), - ('rhodecode', 'RC_SCM_DATA', '[["foo","FOO","bar","BAR"]]') + ("vcs_git_lfs", "store_location", hg_config_org.get("vcs_git_lfs", "store_location")), + ("largefiles", "usercache", hg_config_org.get("largefiles", "usercache")), + ("vcs_svn_branch", "9aac1a38c3b8a0cdc4ae0f960a5f83332bc4fa5e", "/branches/*"), + ("vcs_svn_branch", "c7e6a611c87da06529fd0dd733308481d67c71a8", "/trunk"), + ("hooks", "preoutgoing.pre_pull", "python:vcsserver.hooks.pre_pull"), + ("hooks", "prechangegroup.pre_push", "python:vcsserver.hooks.pre_push"), + ("hooks", "outgoing.pull_logger", "python:vcsserver.hooks.log_pull_action"), + ("hooks", "pretxnchangegroup.pre_push", "python:vcsserver.hooks.pre_push"), + ("hooks", "changegroup.push_logger", "python:vcsserver.hooks.log_push_action"), + ("hooks", "changegroup.repo_size", "python:vcsserver.hooks.repo_size"), + ("phases", "publish", "True"), + ("extensions", "largefiles", ""), + ("paths", "/", hg_config_org.get("paths", "/")), + ("rhodecode", "RC_SCM_DATA", '[["foo","FOO","bar","BAR"]]'), ] for entry in expected_config: assert entry in hg_config @@ -147,11 +140,10 @@ def test_get_config(user_util, baseapp, request_stub): def test_create_wsgi_app_uses_scm_app_from_simplevcs(request_stub): config = { - 'auth_ret_code': '', - 'base_path': '', - 'vcs.scm_app_implementation': - 'rhodecode.tests.lib.middleware.mock_scm_app', + "auth_ret_code": "", + "base_path": "", + "vcs.scm_app_implementation": "rhodecode.tests.lib.middleware.mock_scm_app", } app = simplehg.SimpleHg(config=config, registry=request_stub.registry) - wsgi_app = app._create_wsgi_app('/tmp/test', 'test_repo', {}) + wsgi_app = app._create_wsgi_app("/tmp/test", "test_repo", {}) assert wsgi_app is mock_scm_app.mock_hg_wsgi diff --git a/rhodecode/tests/lib/middleware/test_simplesvn.py b/rhodecode/tests/lib/middleware/test_simplesvn.py index 8ffe266c..31922b14 100644 --- a/rhodecode/tests/lib/middleware/test_simplesvn.py +++ b/rhodecode/tests/lib/middleware/test_simplesvn.py @@ -30,154 +30,148 @@ class TestSimpleSvn(object): @pytest.fixture(autouse=True) def simple_svn(self, baseapp, request_stub): base_path = get_rhodecode_repo_store_path() - self.app = SimpleSvn( - config={'auth_ret_code': '', 'repo_store.path': base_path}, - registry=request_stub.registry) + self.app = SimpleSvn(config={"auth_ret_code": "", "repo_store.path": base_path}, registry=request_stub.registry) def test_get_config(self): - extras = {'foo': 'FOO', 'bar': 'BAR'} - config = self.app._create_config(extras, repo_name='test-repo') + extras = {"foo": "FOO", "bar": "BAR"} + config = self.app._create_config(extras, repo_name="test-repo") assert config == extras - @pytest.mark.parametrize( - 'method', ['OPTIONS', 'PROPFIND', 'GET', 'REPORT']) + @pytest.mark.parametrize("method", ["OPTIONS", "PROPFIND", "GET", "REPORT"]) def test_get_action_returns_pull(self, method): - environment = {'REQUEST_METHOD': method} + environment = {"REQUEST_METHOD": method} action = self.app._get_action(environment) - assert action == 'pull' + assert action == "pull" @pytest.mark.parametrize( - 'method', [ - 'MKACTIVITY', 'PROPPATCH', 'PUT', 'CHECKOUT', 'MKCOL', 'MOVE', - 'COPY', 'DELETE', 'LOCK', 'UNLOCK', 'MERGE' - ]) + "method", + ["MKACTIVITY", "PROPPATCH", "PUT", "CHECKOUT", "MKCOL", "MOVE", "COPY", "DELETE", "LOCK", "UNLOCK", "MERGE"], + ) def test_get_action_returns_push(self, method): - environment = {'REQUEST_METHOD': method} + environment = {"REQUEST_METHOD": method} action = self.app._get_action(environment) - assert action == 'push' + assert action == "push" @pytest.mark.parametrize( - 'path, expected_name', [ - ('/hello-svn', 'hello-svn'), - ('/hello-svn/', 'hello-svn'), - ('/group/hello-svn/', 'group/hello-svn'), - ('/group/hello-svn/!svn/vcc/default', 'group/hello-svn'), - ]) + "path, expected_name", + [ + ("/hello-svn", "hello-svn"), + ("/hello-svn/", "hello-svn"), + ("/group/hello-svn/", "group/hello-svn"), + ("/group/hello-svn/!svn/vcc/default", "group/hello-svn"), + ], + ) def test_get_repository_name(self, path, expected_name): - environment = {'PATH_INFO': path} + environment = {"PATH_INFO": path} name = self.app._get_repository_name(environment) assert name == expected_name def test_get_repository_name_subfolder(self, backend_svn): repo = backend_svn.repo - environment = { - 'PATH_INFO': '/{}/path/with/subfolders'.format(repo.repo_name)} + environment = {"PATH_INFO": "/{}/path/with/subfolders".format(repo.repo_name)} name = self.app._get_repository_name(environment) assert name == repo.repo_name def test_create_wsgi_app(self): - with patch.object(SimpleSvn, '_is_svn_enabled') as mock_method: + with patch.object(SimpleSvn, "_is_svn_enabled") as mock_method: mock_method.return_value = False - with patch('rhodecode.lib.middleware.simplesvn.DisabledSimpleSvnApp') as ( - wsgi_app_mock): + with patch("rhodecode.lib.middleware.simplesvn.DisabledSimpleSvnApp") as (wsgi_app_mock): config = Mock() - wsgi_app = self.app._create_wsgi_app( - repo_path='', repo_name='', config=config) + wsgi_app = self.app._create_wsgi_app(repo_path="", repo_name="", config=config) wsgi_app_mock.assert_called_once_with(config) assert wsgi_app == wsgi_app_mock() def test_create_wsgi_app_when_enabled(self): - with patch.object(SimpleSvn, '_is_svn_enabled') as mock_method: + with patch.object(SimpleSvn, "_is_svn_enabled") as mock_method: mock_method.return_value = True - with patch('rhodecode.lib.middleware.simplesvn.SimpleSvnApp') as ( - wsgi_app_mock): + with patch("rhodecode.lib.middleware.simplesvn.SimpleSvnApp") as (wsgi_app_mock): config = Mock() - wsgi_app = self.app._create_wsgi_app( - repo_path='', repo_name='', config=config) + wsgi_app = self.app._create_wsgi_app(repo_path="", repo_name="", config=config) wsgi_app_mock.assert_called_once_with(config) assert wsgi_app == wsgi_app_mock() def basic_auth(username, password): - token = b64encode(f"{username}:{password}".encode('utf-8')).decode("ascii") - return f'Basic {token}' + token = b64encode(f"{username}:{password}".encode("utf-8")).decode("ascii") + return f"Basic {token}" class TestSimpleSvnApp(object): - data = b'' + data = b"" path = SVN_REPO wsgi_input = io.BytesIO(data) environment = { - 'HTTP_DAV': ( - 'http://subversion.tigris.org/xmlns/dav/svn/depth, ' - 'http://subversion.tigris.org/xmlns/dav/svn/mergeinfo'), - 'HTTP_USER_AGENT': 'SVN/1.14.1 (x86_64-linux) serf/1.3.8', - 'REQUEST_METHOD': 'OPTIONS', - 'PATH_INFO': path, - 'wsgi.input': wsgi_input, - 'CONTENT_TYPE': 'text/xml', - 'CONTENT_LENGTH': '130', - 'Authorization': basic_auth(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) + "HTTP_DAV": ( + "http://subversion.tigris.org/xmlns/dav/svn/depth, http://subversion.tigris.org/xmlns/dav/svn/mergeinfo" + ), + "HTTP_USER_AGENT": "SVN/1.14.1 (x86_64-linux) serf/1.3.8", + "REQUEST_METHOD": "OPTIONS", + "PATH_INFO": path, + "wsgi.input": wsgi_input, + "CONTENT_TYPE": "text/xml", + "CONTENT_LENGTH": "130", + "Authorization": basic_auth(TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS), } def setup_method(self, method): # note(marcink): this is hostname from docker compose used for testing... - self.host = 'http://svn:8090' + self.host = "http://svn:8090" base_path = get_rhodecode_repo_store_path() - self.app = SimpleSvnApp( - config={'subversion_http_server_url': self.host, - 'base_path': base_path}) + self.app = SimpleSvnApp(config={"subversion_http_server_url": self.host, "base_path": base_path}) def test_get_request_headers_with_content_type(self): expected_headers = { - 'Dav': self.environment['HTTP_DAV'], - 'User-Agent': self.environment['HTTP_USER_AGENT'], - 'Content-Type': self.environment['CONTENT_TYPE'], - 'Content-Length': self.environment['CONTENT_LENGTH'], - 'Authorization': self.environment['Authorization'] + "Dav": self.environment["HTTP_DAV"], + "User-Agent": self.environment["HTTP_USER_AGENT"], + "Content-Type": self.environment["CONTENT_TYPE"], + "Content-Length": self.environment["CONTENT_LENGTH"], + "Authorization": self.environment["Authorization"], } headers = self.app._get_request_headers(self.environment) assert headers == expected_headers def test_get_request_headers_without_content_type(self): environment = self.environment.copy() - environment.pop('CONTENT_TYPE') + environment.pop("CONTENT_TYPE") expected_headers = { - 'Dav': environment['HTTP_DAV'], - 'Content-Length': self.environment['CONTENT_LENGTH'], - 'User-Agent': environment['HTTP_USER_AGENT'], - 'Authorization': self.environment['Authorization'] + "Dav": environment["HTTP_DAV"], + "Content-Length": self.environment["CONTENT_LENGTH"], + "User-Agent": environment["HTTP_USER_AGENT"], + "Authorization": self.environment["Authorization"], } request_headers = self.app._get_request_headers(environment) assert request_headers == expected_headers def test_get_response_headers(self): headers = { - 'Connection': 'keep-alive', - 'Keep-Alive': 'timeout=5, max=100', - 'Transfer-Encoding': 'chunked', - 'Content-Encoding': 'gzip', - 'MS-Author-Via': 'DAV', - 'SVN-Supported-Posts': 'create-txn-with-props' + "Connection": "keep-alive", + "Keep-Alive": "timeout=5, max=100", + "Transfer-Encoding": "chunked", + "Content-Encoding": "gzip", + "MS-Author-Via": "DAV", + "SVN-Supported-Posts": "create-txn-with-props", } expected_headers = [ - ('MS-Author-Via', 'DAV'), - ('SVN-Supported-Posts', 'create-txn-with-props'), + ("MS-Author-Via", "DAV"), + ("SVN-Supported-Posts", "create-txn-with-props"), ] response_headers = self.app._get_response_headers(headers) assert sorted(response_headers) == sorted(expected_headers) - @pytest.mark.parametrize('svn_http_url, path_info, expected_url', [ - ('http://localhost:8200', '/repo_name', 'http://localhost:8200/repo_name'), - ('http://localhost:8200///', '/repo_name', 'http://localhost:8200/repo_name'), - ('http://localhost:8200', '/group/repo_name', 'http://localhost:8200/group/repo_name'), - ('http://localhost:8200/', '/group/repo_name', 'http://localhost:8200/group/repo_name'), - ('http://localhost:8200/prefix', '/repo_name', 'http://localhost:8200/prefix/repo_name'), - ('http://localhost:8200/prefix', 'repo_name', 'http://localhost:8200/prefix/repo_name'), - ('http://localhost:8200/prefix', '/group/repo_name', 'http://localhost:8200/prefix/group/repo_name') - ]) + @pytest.mark.parametrize( + "svn_http_url, path_info, expected_url", + [ + ("http://localhost:8200", "/repo_name", "http://localhost:8200/repo_name"), + ("http://localhost:8200///", "/repo_name", "http://localhost:8200/repo_name"), + ("http://localhost:8200", "/group/repo_name", "http://localhost:8200/group/repo_name"), + ("http://localhost:8200/", "/group/repo_name", "http://localhost:8200/group/repo_name"), + ("http://localhost:8200/prefix", "/repo_name", "http://localhost:8200/prefix/repo_name"), + ("http://localhost:8200/prefix", "repo_name", "http://localhost:8200/prefix/repo_name"), + ("http://localhost:8200/prefix", "/group/repo_name", "http://localhost:8200/prefix/group/repo_name"), + ], + ) def test_get_url(self, svn_http_url, path_info, expected_url): url = self.app._get_url(svn_http_url, path_info) assert url == expected_url @@ -186,26 +180,27 @@ class TestSimpleSvnApp(object): start_response = Mock() response_mock = Mock() response_mock.headers = { - 'Content-Encoding': 'gzip', - 'MS-Author-Via': 'DAV', - 'SVN-Supported-Posts': 'create-txn-with-props' + "Content-Encoding": "gzip", + "MS-Author-Via": "DAV", + "SVN-Supported-Posts": "create-txn-with-props", } from rhodecode.lib.middleware.simplesvn import requests + original_request = requests.Session.request - with patch('rhodecode.lib.middleware.simplesvn.requests.Session.request', autospec=True) as request_mock: + with patch("rhodecode.lib.middleware.simplesvn.requests.Session.request", autospec=True) as request_mock: # Use side_effect to call the original method request_mock.side_effect = original_request self.app(self.environment, start_response) - expected_url = f'{self.host.strip("/")}/{self.path}' + expected_url = f"{self.host.strip('/')}/{self.path}" expected_request_headers = { - 'Dav': self.environment['HTTP_DAV'], - 'User-Agent': self.environment['HTTP_USER_AGENT'], - 'Authorization': self.environment['Authorization'], - 'Content-Type': self.environment['CONTENT_TYPE'], - 'Content-Length': self.environment['CONTENT_LENGTH'], + "Dav": self.environment["HTTP_DAV"], + "User-Agent": self.environment["HTTP_USER_AGENT"], + "Authorization": self.environment["Authorization"], + "Content-Type": self.environment["CONTENT_TYPE"], + "Content-Length": self.environment["CONTENT_LENGTH"], } # Check if the method was called @@ -217,15 +212,19 @@ class TestSimpleSvnApp(object): request_mock.assert_called_once_with( called_with_session, - self.environment['REQUEST_METHOD'], expected_url, - data=self.data, headers=expected_request_headers, stream=False) + self.environment["REQUEST_METHOD"], + expected_url, + data=self.data, + headers=expected_request_headers, + stream=False, + ) expected_response_headers = [ - ('SVN-Supported-Posts', 'create-txn-with-props'), - ('MS-Author-Via', 'DAV'), + ("SVN-Supported-Posts", "create-txn-with-props"), + ("MS-Author-Via", "DAV"), ] # TODO: the svn doesn't have a repo for testing - #args, _ = start_response.call_args - #assert args[0] == '200 OK' - #assert sorted(args[1]) == sorted(expected_response_headers) + # args, _ = start_response.call_args + # assert args[0] == '200 OK' + # assert sorted(args[1]) == sorted(expected_response_headers) diff --git a/rhodecode/tests/lib/middleware/test_simplevcs.py b/rhodecode/tests/lib/middleware/test_simplevcs.py index dde71564..28ea672b 100644 --- a/rhodecode/tests/lib/middleware/test_simplevcs.py +++ b/rhodecode/tests/lib/middleware/test_simplevcs.py @@ -30,8 +30,7 @@ from rhodecode.lib.middleware.https_fixup import HttpsFixup from rhodecode.lib.middleware.utils import scm_app_http from rhodecode.model.db import User, _hash_key from rhodecode.model.meta import Session, cache as db_cache -from rhodecode.tests import ( - HG_REPO, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS) +from rhodecode.tests import HG_REPO, TEST_USER_ADMIN_LOGIN, TEST_USER_ADMIN_PASS from rhodecode.tests.lib.middleware import mock_scm_app from rhodecode.model.db import Permission, User @@ -54,13 +53,14 @@ def enable_auth_plugins(request, app): @pytest.fixture() def test_user_factory(request, baseapp): - - def user_factory(username='test_user', password='qweqwe', first_name='John', last_name='Testing', **kwargs): + def user_factory(username="test_user", password="qweqwe", first_name="John", last_name="Testing", **kwargs): usr = UserModel().create_or_update( username=username, password=password, - email=f'{username}@rhodecode.org', - firstname=first_name, lastname=last_name) + email=f"{username}@rhodecode.org", + firstname=first_name, + lastname=last_name, + ) Session().commit() for k, v in kwargs.items(): @@ -82,18 +82,19 @@ def test_user_factory(request, baseapp): UserModel().delete(new_usr_id) Session().commit() + return usr return user_factory -class StubVCSController(simplevcs.SimpleVCS): - SCM = 'hg' +class StubVCSController(simplevcs.SimpleVCS): + SCM = "hg" stub_response_body = tuple() def __init__(self, *args, **kwargs): super(StubVCSController, self).__init__(*args, **kwargs) - self._action = 'pull' + self._action = "pull" self._is_shadow_repo_dir = True self._name = HG_REPO self.set_repo_names(None) @@ -110,14 +111,13 @@ class StubVCSController(simplevcs.SimpleVCS): def _create_wsgi_app(self, repo_path, repo_name, config): def fake_app(environ, start_response): - headers = [ - ('Http-Accept', 'application/mercurial') - ] - start_response('200 OK', headers) + headers = [("Http-Accept", "application/mercurial")] + start_response("200 OK", headers) return self.stub_response_body + return fake_app - def _create_config(self, extras, repo_name, scheme='http'): + def _create_config(self, extras, repo_name, scheme="http"): return None @@ -126,20 +126,19 @@ def vcscontroller(baseapp, config_stub, request_stub): from rhodecode.config.middleware import ce_auth_resources config_stub.testing_securitypolicy() - config_stub.include('rhodecode.authentication') + config_stub.include("rhodecode.authentication") for resource in ce_auth_resources: config_stub.include(resource) - controller = StubVCSController( - baseapp.config.get_settings(), request_stub.registry) + controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) app = HttpsFixup(controller, baseapp.config.get_settings()) app = CustomTestApp(app) _remove_default_user_from_query_cache() # Sanity checks that things are set up correctly - app.get('/' + HG_REPO, status=200) + app.get("/" + HG_REPO, status=200) app.controller = controller return app @@ -148,48 +147,48 @@ def vcscontroller(baseapp, config_stub, request_stub): def _remove_default_user_from_query_cache(): user = User.get_default_user(cache=True) query = Session().query(User).filter(User.username == user.username) - query = query.options( - FromCache("sql_cache_short", f"get_user_{_hash_key(user.username)}")) + query = query.options(FromCache("sql_cache_short", f"get_user_{_hash_key(user.username)}")) - db_cache.invalidate( - query, {}, - FromCache("sql_cache_short", f"get_user_{_hash_key(user.username)}")) + db_cache.invalidate(query, {}, FromCache("sql_cache_short", f"get_user_{_hash_key(user.username)}")) Session().expire(user) -def test_handles_exceptions_during_permissions_checks(vcscontroller, disable_anonymous_user, enable_auth_plugins, test_user_factory): - - test_password = 'qweqwe' - test_user = test_user_factory(password=test_password, extern_type='headers', extern_name='headers') +def test_handles_exceptions_during_permissions_checks( + vcscontroller, disable_anonymous_user, enable_auth_plugins, test_user_factory +): + test_password = "qweqwe" + test_user = test_user_factory(password=test_password, extern_type="headers", extern_name="headers") test_username = test_user.username - enable_auth_plugins.enable([ - 'egg:rhodecode-enterprise-ce#headers', - 'egg:rhodecode-enterprise-ce#token', - 'egg:rhodecode-enterprise-ce#rhodecode'], - override={ - 'egg:rhodecode-enterprise-ce#headers': {'auth_headers_header': 'REMOTE_USER'} - }) + enable_auth_plugins.enable( + [ + "egg:rhodecode-enterprise-ce#headers", + "egg:rhodecode-enterprise-ce#token", + "egg:rhodecode-enterprise-ce#rhodecode", + ], + override={"egg:rhodecode-enterprise-ce#headers": {"auth_headers_header": "REMOTE_USER"}}, + ) - user_and_pass = f'{test_username}:{test_password}' + user_and_pass = f"{test_username}:{test_password}" auth_password = base64_to_str(user_and_pass) extra_environ = { - 'AUTH_TYPE': 'Basic', - 'HTTP_AUTHORIZATION': f'Basic {auth_password}', - 'REMOTE_USER': test_username, + "AUTH_TYPE": "Basic", + "HTTP_AUTHORIZATION": f"Basic {auth_password}", + "REMOTE_USER": test_username, } # Verify that things are hooked up correctly, we pass user with headers bound auth, and headers filled in - vcscontroller.get('/', status=200, extra_environ=extra_environ) + vcscontroller.get("/", status=200, extra_environ=extra_environ) # Simulate trouble during permission checks - with mock.patch('rhodecode.model.db.User.get_by_username', - side_effect=Exception('permission_error_test')) as get_user: + with mock.patch( + "rhodecode.model.db.User.get_by_username", side_effect=Exception("permission_error_test") + ) as get_user: # Verify that a correct 500 is returned and check that the expected # code path was hit. - vcscontroller.get('/', status=500, extra_environ=extra_environ) + vcscontroller.get("/", status=500, extra_environ=extra_environ) assert get_user.called @@ -198,23 +197,21 @@ class StubFailVCSController(simplevcs.SimpleVCS): raise Exception("BOOM") -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def fail_controller(baseapp): - controller = StubFailVCSController( - baseapp.config.get_settings(), baseapp.config) + controller = StubFailVCSController(baseapp.config.get_settings(), baseapp.config) controller = HttpsFixup(controller, baseapp.config.get_settings()) controller = CustomTestApp(controller) return controller def test_handles_exceptions_as_internal_server_error(fail_controller): - fail_controller.get('/', status=500) + fail_controller.get("/", status=500) def test_provides_traceback_for_appenlight(fail_controller): - response = fail_controller.get( - '/', status=500, extra_environ={'appenlight.client': 'fake'}) - assert 'appenlight.__traceback' in response.request.environ + response = fail_controller.get("/", status=500, extra_environ={"appenlight.client": "fake"}) + assert "appenlight.__traceback" in response.request.environ def test_provides_utils_scm_app_as_scm_app_by_default(baseapp, request_stub): @@ -224,137 +221,131 @@ def test_provides_utils_scm_app_as_scm_app_by_default(baseapp, request_stub): def test_allows_to_override_scm_app_via_config(baseapp, request_stub): config = baseapp.config.get_settings().copy() - config['vcs.scm_app_implementation'] = ( - 'rhodecode.tests.lib.middleware.mock_scm_app') + config["vcs.scm_app_implementation"] = "rhodecode.tests.lib.middleware.mock_scm_app" controller = StubVCSController(config, request_stub.registry) assert controller.scm_app is mock_scm_app -@pytest.mark.parametrize('query_string, expected', [ - ('cmd=stub_command', True), - ('cmd=listkeys', False), -]) +@pytest.mark.parametrize( + "query_string, expected", + [ + ("cmd=stub_command", True), + ("cmd=listkeys", False), + ], +) def test_should_check_locking(query_string, expected): result = simplevcs._should_check_locking(query_string) assert result == expected class TestShadowRepoRegularExpression(object): - pr_segment = 'pull-request' - shadow_segment = 'repository' + pr_segment = "pull-request" + shadow_segment = "repository" - @pytest.mark.parametrize('url, expected', [ - # repo with/without groups - ('My-Repo/{pr_segment}/1/{shadow_segment}', True), - ('Group/My-Repo/{pr_segment}/2/{shadow_segment}', True), - ('Group/Sub-Group/My-Repo/{pr_segment}/3/{shadow_segment}', True), - ('Group/Sub-Group1/Sub-Group2/My-Repo/{pr_segment}/3/{shadow_segment}', True), - - # pull request ID - ('MyRepo/{pr_segment}/1/{shadow_segment}', True), - ('MyRepo/{pr_segment}/1234567890/{shadow_segment}', True), - ('MyRepo/{pr_segment}/-1/{shadow_segment}', False), - ('MyRepo/{pr_segment}/invalid/{shadow_segment}', False), - - # unicode - (u'Sp€çîál-Repö/{pr_segment}/1/{shadow_segment}', True), - (u'Sp€çîál-Gröüp/Sp€çîál-Repö/{pr_segment}/1/{shadow_segment}', True), - - # trailing/leading slash - ('/My-Repo/{pr_segment}/1/{shadow_segment}', False), - ('My-Repo/{pr_segment}/1/{shadow_segment}/', False), - ('/My-Repo/{pr_segment}/1/{shadow_segment}/', False), - - # misc - ('My-Repo/{pr_segment}/1/{shadow_segment}/extra', False), - ('My-Repo/{pr_segment}/1/{shadow_segment}extra', False), - ]) + @pytest.mark.parametrize( + "url, expected", + [ + # repo with/without groups + ("My-Repo/{pr_segment}/1/{shadow_segment}", True), + ("Group/My-Repo/{pr_segment}/2/{shadow_segment}", True), + ("Group/Sub-Group/My-Repo/{pr_segment}/3/{shadow_segment}", True), + ("Group/Sub-Group1/Sub-Group2/My-Repo/{pr_segment}/3/{shadow_segment}", True), + # pull request ID + ("MyRepo/{pr_segment}/1/{shadow_segment}", True), + ("MyRepo/{pr_segment}/1234567890/{shadow_segment}", True), + ("MyRepo/{pr_segment}/-1/{shadow_segment}", False), + ("MyRepo/{pr_segment}/invalid/{shadow_segment}", False), + # unicode + ("Sp€çîál-Repö/{pr_segment}/1/{shadow_segment}", True), + ("Sp€çîál-Gröüp/Sp€çîál-Repö/{pr_segment}/1/{shadow_segment}", True), + # trailing/leading slash + ("/My-Repo/{pr_segment}/1/{shadow_segment}", False), + ("My-Repo/{pr_segment}/1/{shadow_segment}/", False), + ("/My-Repo/{pr_segment}/1/{shadow_segment}/", False), + # misc + ("My-Repo/{pr_segment}/1/{shadow_segment}/extra", False), + ("My-Repo/{pr_segment}/1/{shadow_segment}extra", False), + ], + ) def test_shadow_repo_regular_expression(self, url, expected): from rhodecode.lib.middleware.simplevcs import SimpleVCS - url = url.format( - pr_segment=self.pr_segment, - shadow_segment=self.shadow_segment) + + url = url.format(pr_segment=self.pr_segment, shadow_segment=self.shadow_segment) match_obj = SimpleVCS.shadow_repo_re.match(url) assert (match_obj is not None) == expected -@pytest.mark.backends('git', 'hg') +@pytest.mark.backends("git", "hg") class TestShadowRepoExposure(object): - - def test_pull_on_shadow_repo_propagates_to_wsgi_app( - self, baseapp, request_stub): + def test_pull_on_shadow_repo_propagates_to_wsgi_app(self, baseapp, request_stub): """ Check that a pull action to a shadow repo is propagated to the underlying wsgi app. """ - controller = StubVCSController( - baseapp.config.get_settings(), request_stub.registry) + controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) controller.is_shadow_repo = True - controller._action = 'pull' + controller._action = "pull" controller._is_shadow_repo_dir = True - controller.stub_response_body = (b'dummy body value',) - controller._get_default_cache_ttl = mock.Mock( - return_value=(False, 0)) + controller.stub_response_body = (b"dummy body value",) + controller._get_default_cache_ttl = mock.Mock(return_value=(False, 0)) environ_stub = { - 'HTTP_HOST': 'test.example.com', - 'HTTP_ACCEPT': 'application/mercurial', - 'REQUEST_METHOD': 'GET', - 'wsgi.url_scheme': 'http', + "HTTP_HOST": "test.example.com", + "HTTP_ACCEPT": "application/mercurial", + "REQUEST_METHOD": "GET", + "wsgi.url_scheme": "http", } response = controller(environ_stub, mock.Mock()) - response_body = b''.join(response) + response_body = b"".join(response) # Assert that we got the response from the wsgi app. - assert response_body == b''.join(controller.stub_response_body) + assert response_body == b"".join(controller.stub_response_body) def test_pull_on_shadow_repo_that_is_missing(self, baseapp, request_stub): """ Check that a pull action to a shadow repo is propagated to the underlying wsgi app. """ - controller = StubVCSController( - baseapp.config.get_settings(), request_stub.registry) + controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) controller.is_shadow_repo = True - controller._action = 'pull' + controller._action = "pull" controller._is_shadow_repo_dir = False - controller.stub_response_body = (b'dummy body value',) + controller.stub_response_body = (b"dummy body value",) environ_stub = { - 'HTTP_HOST': 'test.example.com', - 'HTTP_ACCEPT': 'application/mercurial', - 'REQUEST_METHOD': 'GET', - 'wsgi.url_scheme': 'http', + "HTTP_HOST": "test.example.com", + "HTTP_ACCEPT": "application/mercurial", + "REQUEST_METHOD": "GET", + "wsgi.url_scheme": "http", } response = controller(environ_stub, mock.Mock()) - response_body = b''.join(response) + response_body = b"".join(response) # Assert that we got the response from the wsgi app. - assert b'404 Not Found' in response_body + assert b"404 Not Found" in response_body def test_push_on_shadow_repo_raises(self, baseapp, request_stub): """ Check that a push action to a shadow repo is aborted. """ - controller = StubVCSController( - baseapp.config.get_settings(), request_stub.registry) + controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) controller.is_shadow_repo = True - controller._action = 'push' - controller.stub_response_body = (b'dummy body value',) + controller._action = "push" + controller.stub_response_body = (b"dummy body value",) environ_stub = { - 'HTTP_HOST': 'test.example.com', - 'HTTP_ACCEPT': 'application/mercurial', - 'REQUEST_METHOD': 'GET', - 'wsgi.url_scheme': 'http', + "HTTP_HOST": "test.example.com", + "HTTP_ACCEPT": "application/mercurial", + "REQUEST_METHOD": "GET", + "wsgi.url_scheme": "http", } response = controller(environ_stub, mock.Mock()) - response_body = b''.join(response) + response_body = b"".join(response) assert response_body != controller.stub_response_body # Assert that a 406 error is returned. - assert b'406 Not Acceptable' in response_body + assert b"406 Not Acceptable" in response_body def test_set_repo_names_no_shadow(self, baseapp, request_stub): """ @@ -362,18 +353,18 @@ class TestShadowRepoExposure(object): by the _get_repository_name method on a request to a non shadow repo. """ environ_stub = {} - controller = StubVCSController( - baseapp.config.get_settings(), request_stub.registry) - controller._name = 'RepoGroup/MyRepo' + controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) + controller._name = "RepoGroup/MyRepo" controller.set_repo_names(environ_stub) assert not controller.is_shadow_repo - assert (controller.url_repo_name == - controller.acl_repo_name == - controller.vcs_repo_name == - controller._get_repository_name(environ_stub)) + assert ( + controller.url_repo_name + == controller.acl_repo_name + == controller.vcs_repo_name + == controller._get_repository_name(environ_stub) + ) - def test_set_repo_names_with_shadow( - self, baseapp, pr_util, config_stub, request_stub): + def test_set_repo_names_with_shadow(self, baseapp, pr_util, config_stub, request_stub): """ Check that the set_repo_names method sets correct names on a request to a shadow repo. @@ -381,13 +372,13 @@ class TestShadowRepoExposure(object): from rhodecode.model.pull_request import PullRequestModel pull_request = pr_util.create_pull_request() - shadow_url = '{target}/{pr_segment}/{pr_id}/{shadow_segment}'.format( + shadow_url = "{target}/{pr_segment}/{pr_id}/{shadow_segment}".format( target=pull_request.target_repo.repo_name, pr_id=pull_request.pull_request_id, pr_segment=TestShadowRepoRegularExpression.pr_segment, - shadow_segment=TestShadowRepoRegularExpression.shadow_segment) - controller = StubVCSController( - baseapp.config.get_settings(), request_stub.registry) + shadow_segment=TestShadowRepoRegularExpression.shadow_segment, + ) + controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) controller._name = shadow_url controller.set_repo_names({}) @@ -400,55 +391,50 @@ class TestShadowRepoExposure(object): assert controller.acl_repo_name == pull_request.target_repo.repo_name assert controller.is_shadow_repo - def test_set_repo_names_with_shadow_but_missing_pr( - self, baseapp, pr_util, config_stub, request_stub): + def test_set_repo_names_with_shadow_but_missing_pr(self, baseapp, pr_util, config_stub, request_stub): """ Checks that the set_repo_names method enforces matching target repos and pull request IDs. """ pull_request = pr_util.create_pull_request() - shadow_url = '{target}/{pr_segment}/{pr_id}/{shadow_segment}'.format( + shadow_url = "{target}/{pr_segment}/{pr_id}/{shadow_segment}".format( target=pull_request.target_repo.repo_name, pr_id=999999999, pr_segment=TestShadowRepoRegularExpression.pr_segment, - shadow_segment=TestShadowRepoRegularExpression.shadow_segment) - controller = StubVCSController( - baseapp.config.get_settings(), request_stub.registry) + shadow_segment=TestShadowRepoRegularExpression.shadow_segment, + ) + controller = StubVCSController(baseapp.config.get_settings(), request_stub.registry) controller._name = shadow_url controller.set_repo_names({}) assert not controller.is_shadow_repo - assert (controller.url_repo_name == - controller.acl_repo_name == - controller.vcs_repo_name) + assert controller.url_repo_name == controller.acl_repo_name == controller.vcs_repo_name class TestGenerateVcsResponse(object): - def test_ensures_that_start_response_is_called_early_enough(self, baseapp): - app_ini_config = baseapp.config.registry.settings['__file__'] - self.call_controller_with_response_body(app_ini_config, iter(['a', 'b'])) + app_ini_config = baseapp.config.registry.settings["__file__"] + self.call_controller_with_response_body(app_ini_config, iter(["a", "b"])) assert self.start_response.called def test_invalidates_cache_after_body_is_consumed(self, baseapp): - app_ini_config = baseapp.config.registry.settings['__file__'] - result = self.call_controller_with_response_body(app_ini_config, iter(['a', 'b'])) + app_ini_config = baseapp.config.registry.settings["__file__"] + result = self.call_controller_with_response_body(app_ini_config, iter(["a", "b"])) assert not self.was_cache_invalidated() # Consume the result list(result) assert self.was_cache_invalidated() def test_raises_unknown_exceptions(self, baseapp): - app_ini_config = baseapp.config.registry.settings['__file__'] - result = self.call_controller_with_response_body(app_ini_config, self.raise_result_iter(vcs_kind='unknown')) + app_ini_config = baseapp.config.registry.settings["__file__"] + result = self.call_controller_with_response_body(app_ini_config, self.raise_result_iter(vcs_kind="unknown")) with pytest.raises(Exception): list(result) def call_controller_with_response_body(self, ini_config, response_body): - settings = { - 'vcs.hooks.protocol.v2': 'celery', - 'vcs.hooks.direct_calls': False, + "vcs.hooks.protocol.v2": "celery", + "vcs.hooks.direct_calls": False, } registry = AttributeDict() controller = StubVCSController(settings, registry) @@ -456,21 +442,24 @@ class TestGenerateVcsResponse(object): controller.stub_response_body = response_body self.start_response = mock.Mock() result = controller._generate_vcs_response( - environ={}, start_response=self.start_response, - repo_path='fake_repo_path', - extras={'config': ini_config}, action='push') + environ={}, + start_response=self.start_response, + repo_path="fake_repo_path", + extras={"config": ini_config}, + action="push", + ) self.controller = controller return result - def raise_result_iter(self, vcs_kind='repo_locked'): + def raise_result_iter(self, vcs_kind="repo_locked"): """ Simulates an exception due to a vcs raised exception if kind vcs_kind """ raise self.vcs_exception(vcs_kind=vcs_kind) yield "never_reached" - def vcs_exception(self, vcs_kind='repo_locked'): - locked_exception = Exception('TEST_MESSAGE') + def vcs_exception(self, vcs_kind="repo_locked"): + locked_exception = Exception("TEST_MESSAGE") locked_exception._vcs_kind = vcs_kind return locked_exception @@ -479,16 +468,18 @@ class TestGenerateVcsResponse(object): class TestInitializeGenerator(object): - def test_drains_first_element(self): - gen = self.factory(['__init__', 1, 2]) + gen = self.factory(["__init__", 1, 2]) result = list(gen) assert result == [1, 2] - @pytest.mark.parametrize('values', [ - [], - [1, 2], - ]) + @pytest.mark.parametrize( + "values", + [ + [], + [1, 2], + ], + ) def test_raises_value_error(self, values): with pytest.raises(ValueError): self.factory(values) diff --git a/rhodecode/tests/lib/middleware/test_vcs.py b/rhodecode/tests/lib/middleware/test_vcs.py index ee6e3cc2..6011b03d 100644 --- a/rhodecode/tests/lib/middleware/test_vcs.py +++ b/rhodecode/tests/lib/middleware/test_vcs.py @@ -20,78 +20,67 @@ from mock import patch, Mock import rhodecode from rhodecode.lib.middleware import vcs -from rhodecode.lib.middleware.simplesvn import ( - SimpleSvn, DisabledSimpleSvnApp, SimpleSvnApp) +from rhodecode.lib.middleware.simplesvn import SimpleSvn, DisabledSimpleSvnApp, SimpleSvnApp from rhodecode.tests import SVN_REPO -svn_repo_path = '/'+ SVN_REPO +svn_repo_path = "/" + SVN_REPO + def test_is_hg(): - environ = { - 'PATH_INFO': svn_repo_path, - 'QUERY_STRING': 'cmd=changegroup', - 'HTTP_ACCEPT': 'application/mercurial' - } + environ = {"PATH_INFO": svn_repo_path, "QUERY_STRING": "cmd=changegroup", "HTTP_ACCEPT": "application/mercurial"} assert vcs.is_hg(environ) def test_is_hg_no_cmd(): - environ = { - 'PATH_INFO': svn_repo_path, - 'QUERY_STRING': '', - 'HTTP_ACCEPT': 'application/mercurial' - } + environ = {"PATH_INFO": svn_repo_path, "QUERY_STRING": "", "HTTP_ACCEPT": "application/mercurial"} assert not vcs.is_hg(environ) def test_is_hg_empty_cmd(): environ = { - 'REQUEST_METHOD': 'GET', - 'PATH_INFO': svn_repo_path, - 'QUERY_STRING': 'cmd=', - 'HTTP_ACCEPT': 'application/mercurial' + "REQUEST_METHOD": "GET", + "PATH_INFO": svn_repo_path, + "QUERY_STRING": "cmd=", + "HTTP_ACCEPT": "application/mercurial", } assert not vcs.is_hg(environ) def test_is_svn_returns_true_if_subversion_is_in_a_dav_header(): environ = { - 'REQUEST_METHOD': 'GET', - 'PATH_INFO': svn_repo_path, - 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log-revprops' + "REQUEST_METHOD": "GET", + "PATH_INFO": svn_repo_path, + "HTTP_DAV": "http://subversion.tigris.org/xmlns/dav/svn/log-revprops", } assert vcs.is_svn(environ) is True def test_is_svn_returns_false_if_subversion_is_not_in_a_dav_header(): environ = { - 'REQUEST_METHOD': 'GET', - 'PATH_INFO': svn_repo_path, - 'HTTP_DAV': 'http://stuff.tigris.org/xmlns/dav/svn/log-revprops' + "REQUEST_METHOD": "GET", + "PATH_INFO": svn_repo_path, + "HTTP_DAV": "http://stuff.tigris.org/xmlns/dav/svn/log-revprops", } assert vcs.is_svn(environ) is False def test_is_svn_returns_false_if_no_dav_header(): environ = { - 'REQUEST_METHOD': 'GET', - 'PATH_INFO': svn_repo_path, + "REQUEST_METHOD": "GET", + "PATH_INFO": svn_repo_path, } assert vcs.is_svn(environ) is False def test_is_svn_returns_true_if_magic_path_segment(): - environ = { - 'PATH_INFO': '/stub-repository/!svn/rev/4', - 'REQUEST_METHOD': 'POST' - } + environ = {"PATH_INFO": "/stub-repository/!svn/rev/4", "REQUEST_METHOD": "POST"} assert vcs.is_svn(environ) def test_is_svn_returns_true_if_propfind(): environ = { - 'REQUEST_METHOD': 'PROPFIND', - 'PATH_INFO': svn_repo_path, + "REQUEST_METHOD": "PROPFIND", + "PATH_INFO": svn_repo_path, } assert vcs.is_svn(environ) is True @@ -101,11 +90,10 @@ def test_is_svn_allows_to_configure_the_magic_path(monkeypatch): This is intended as a fallback in case someone has configured his Subversion server with a different magic path segment. """ - monkeypatch.setitem( - rhodecode.CONFIG, 'rhodecode_subversion_magic_path', '/!my-magic') + monkeypatch.setitem(rhodecode.CONFIG, "rhodecode_subversion_magic_path", "/!my-magic") environ = { - 'REQUEST_METHOD': 'POST', - 'PATH_INFO': '/stub-repository/!my-magic/rev/4', + "REQUEST_METHOD": "POST", + "PATH_INFO": "/stub-repository/!my-magic/rev/4", } assert vcs.is_svn(environ) @@ -113,40 +101,36 @@ def test_is_svn_allows_to_configure_the_magic_path(monkeypatch): class TestVCSMiddleware(object): def test_get_handler_app_retuns_svn_app_when_proxy_enabled(self, app): environ = { - 'PATH_INFO': SVN_REPO, - 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log', - 'REQUEST_METHOD': 'POST' + "PATH_INFO": SVN_REPO, + "HTTP_DAV": "http://subversion.tigris.org/xmlns/dav/svn/log", + "REQUEST_METHOD": "POST", } application = Mock() - config = {'appenlight': False, 'vcs.backends': ['svn']} + config = {"appenlight": False, "vcs.backends": ["svn"]} registry = Mock() - middleware = vcs.VCSMiddleware( - application, registry, config, appenlight_client=None) + middleware = vcs.VCSMiddleware(application, registry, config, appenlight_client=None) middleware.use_gzip = False - with patch.object(SimpleSvn, '_is_svn_enabled') as mock_method: + with patch.object(SimpleSvn, "_is_svn_enabled") as mock_method: mock_method.return_value = True application = middleware._get_handler_app(environ) assert isinstance(application, SimpleSvn) - assert isinstance(application._create_wsgi_app( - Mock(), Mock(), Mock()), SimpleSvnApp) + assert isinstance(application._create_wsgi_app(Mock(), Mock(), Mock()), SimpleSvnApp) def test_get_handler_app_retuns_dummy_svn_app_when_proxy_disabled(self, app): environ = { - 'PATH_INFO': SVN_REPO, - 'HTTP_DAV': 'http://subversion.tigris.org/xmlns/dav/svn/log', - 'REQUEST_METHOD': 'POST' + "PATH_INFO": SVN_REPO, + "HTTP_DAV": "http://subversion.tigris.org/xmlns/dav/svn/log", + "REQUEST_METHOD": "POST", } application = Mock() - config = {'appenlight': False, 'vcs.backends': ['svn']} + config = {"appenlight": False, "vcs.backends": ["svn"]} registry = Mock() - middleware = vcs.VCSMiddleware( - application, registry, config, appenlight_client=None) + middleware = vcs.VCSMiddleware(application, registry, config, appenlight_client=None) middleware.use_gzip = False - with patch.object(SimpleSvn, '_is_svn_enabled') as mock_method: + with patch.object(SimpleSvn, "_is_svn_enabled") as mock_method: mock_method.return_value = False application = middleware._get_handler_app(environ) assert isinstance(application, SimpleSvn) - assert isinstance(application._create_wsgi_app( - Mock(), Mock(), Mock()), DisabledSimpleSvnApp) + assert isinstance(application._create_wsgi_app(Mock(), Mock(), Mock()), DisabledSimpleSvnApp) diff --git a/rhodecode/tests/lib/middleware/test_vcs_unavailable.py b/rhodecode/tests/lib/middleware/test_vcs_unavailable.py index a1e72d95..f27ad879 100644 --- a/rhodecode/tests/lib/middleware/test_vcs_unavailable.py +++ b/rhodecode/tests/lib/middleware/test_vcs_unavailable.py @@ -20,15 +20,15 @@ import mock import pytest -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") def test_vcs_available_returns_summary_page(app, backend): - url = '/{repo_name}'.format(repo_name=backend.repo.repo_name) + url = "/{repo_name}".format(repo_name=backend.repo.repo_name) response = app.get(url) assert response.status_code == 200 - assert 'Summary' in response.text + assert "Summary" in response.text -@pytest.mark.usefixtures('autologin_user', 'app') +@pytest.mark.usefixtures("autologin_user", "app") def test_vcs_unavailable_returns_vcs_error_page(app, backend): from rhodecode.lib.vcs.exceptions import VCSCommunicationError @@ -37,13 +37,13 @@ def test_vcs_unavailable_returns_vcs_error_page(app, backend): # if http is used, it just requires the exception to be raised. from rhodecode.lib.vcs.client_http import RemoteRepo - url = '/{repo_name}'.format(repo_name=backend.repo.repo_name) + url = "/{repo_name}".format(repo_name=backend.repo.repo_name) # Patch remote repo to raise an exception instead of making a RPC. - with mock.patch.object(RemoteRepo, '__getattr__') as remote_mock: + with mock.patch.object(RemoteRepo, "__getattr__") as remote_mock: remote_mock.side_effect = VCSCommunicationError() response = app.get(url, expect_errors=True) assert response.status_code == 502 - assert 'Could not connect to VCS Server' in response.text + assert "Could not connect to VCS Server" in response.text diff --git a/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py b/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py index eb8e8a74..1491282f 100644 --- a/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py +++ b/rhodecode/tests/lib/middleware/utils/test_scm_app_http.py @@ -28,14 +28,13 @@ def vcs_http_app(vcsserver_http_echo_app): """ VcsHttpProxy wrapped in WebTest. """ - git_url = vcsserver_http_echo_app.http_url + 'stream/git/' - vcs_http_proxy = scm_app_http.VcsHttpProxy( - git_url, 'stub_path', 'stub_name', None) + git_url = vcsserver_http_echo_app.http_url + "stream/git/" + vcs_http_proxy = scm_app_http.VcsHttpProxy(git_url, "stub_path", "stub_name", None) app = CustomTestApp(vcs_http_proxy) return app -@pytest.fixture(scope='module') +@pytest.fixture(scope="module") def vcsserver_http_echo_app(request, vcsserver_factory): """ A running VCSServer with the EchoApp activated via HTTP. @@ -43,13 +42,12 @@ def vcsserver_http_echo_app(request, vcsserver_factory): store_dir = tempfile.gettempdir() vcsserver_instance = vcsserver_factory( - request=request, - store_dir=store_dir, - overrides=[{'app:main': {'dev.use_echo_app': 'true'}}]) + request=request, store_dir=store_dir, overrides=[{"app:main": {"dev.use_echo_app": "true"}}] + ) return vcsserver_instance -@pytest.fixture(scope='session') +@pytest.fixture(scope="session") def data(): one_kb = "x" * 1024 return one_kb * 1024 * 10 @@ -58,27 +56,26 @@ def data(): def test_reuse_app_no_data(repeat, vcsserver_http_echo_app): app = vcs_http_app(vcsserver_http_echo_app) for x in range(repeat // 10): - response = app.post('/') + response = app.post("/") assert response.status_code == 200 def test_reuse_app_with_data(data, repeat, vcsserver_http_echo_app): app = vcs_http_app(vcsserver_http_echo_app) for x in range(repeat // 10): - response = app.post('/', params=data) + response = app.post("/", params=data) assert response.status_code == 200 def test_create_app_per_request_no_data(repeat, vcsserver_http_echo_app): for x in range(repeat // 10): app = vcs_http_app(vcsserver_http_echo_app) - response = app.post('/') + response = app.post("/") assert response.status_code == 200 -def test_create_app_per_request_with_data( - data, repeat, vcsserver_http_echo_app): +def test_create_app_per_request_with_data(data, repeat, vcsserver_http_echo_app): for x in range(repeat // 10): app = vcs_http_app(vcsserver_http_echo_app) - response = app.post('/', params=data) + response = app.post("/", params=data) assert response.status_code == 200 diff --git a/rhodecode/tests/lib/middleware/utils/test_scm_app_http_chunking.py b/rhodecode/tests/lib/middleware/utils/test_scm_app_http_chunking.py index 71008eb5..62f758b2 100644 --- a/rhodecode/tests/lib/middleware/utils/test_scm_app_http_chunking.py +++ b/rhodecode/tests/lib/middleware/utils/test_scm_app_http_chunking.py @@ -32,13 +32,13 @@ from rhodecode.tests.utils import wait_for_url def test_does_chunked_end_to_end_transfer(scm_app): - response = requests.post(scm_app, data='', stream=True) - assert response.headers['Transfer-Encoding'] == 'chunked' + response = requests.post(scm_app, data="", stream=True) + assert response.headers["Transfer-Encoding"] == "chunked" times = [time.time() for chunk in response.raw.read_chunked()] assert times[1] - times[0] > 0.1, "Chunks arrived at the same time" -SCM_APP_URL_TMPL = 'http://0.0.0.0:{port}' +SCM_APP_URL_TMPL = "http://0.0.0.0:{port}" @pytest.fixture() @@ -50,11 +50,12 @@ def echo_app_chunking(request, available_port_factory): """ port = available_port_factory() command = ( - 'waitress-serve --send-bytes 1 --port {port} --call ' - 'rhodecode.tests.lib.middleware.utils.test_scm_app_http_chunking' - ':create_echo_app') + "waitress-serve --send-bytes 1 --port {port} --call " + "rhodecode.tests.lib.middleware.utils.test_scm_app_http_chunking" + ":create_echo_app" + ) command = command.format(port=port) - proc = subprocess.Popen(command.split(' '), bufsize=0) + proc = subprocess.Popen(command.split(" "), bufsize=0) echo_app_url = SCM_APP_URL_TMPL.format(port=port) @request.addfinalizer @@ -73,13 +74,14 @@ def scm_app(request, available_port_factory, echo_app_chunking): """ port = available_port_factory() command = ( - 'waitress-serve --send-bytes 1 --port {port} --call ' - 'rhodecode.tests.lib.middleware.utils.test_scm_app_http_chunking' - ':create_scm_app') + "waitress-serve --send-bytes 1 --port {port} --call " + "rhodecode.tests.lib.middleware.utils.test_scm_app_http_chunking" + ":create_scm_app" + ) command = command.format(port=port) env = os.environ.copy() env["RC_ECHO_URL"] = echo_app_chunking - proc = subprocess.Popen(command.split(' '), bufsize=0, env=env) + proc = subprocess.Popen(command.split(" "), bufsize=0, env=env) scm_app_url = SCM_APP_URL_TMPL.format(port=port) wait_for_url(scm_app_url) @@ -99,8 +101,8 @@ class EchoApp(object): self._repo_path = repo_path def __call__(self, environ, start_response): - environ['wsgi.input'].read() - status = '200 OK' + environ["wsgi.input"].read() + status = "200 OK" headers = [] start_response(status, headers) return result_generator() @@ -113,10 +115,10 @@ def result_generator(): The intended usage is to simulate a chunked response as we would get it out of a vcs operation during a call to "hg clone". """ - yield b'waiting 2 seconds' + yield b"waiting 2 seconds" # Wait long enough so that the first chunk can go out time.sleep(2) - yield b'final chunk' + yield b"final chunk" # Another small wait, otherwise they go together time.sleep(0.1) @@ -125,7 +127,7 @@ def create_echo_app(): """ Create EchoApp filled with stub data. """ - return EchoApp('stub_path', 'repo_name', {}) + return EchoApp("stub_path", "repo_name", {}) def create_scm_app(): @@ -133,5 +135,4 @@ def create_scm_app(): Create a scm_app hooked up to speak to EchoApp. """ echo_app_url = os.environ["RC_ECHO_URL"] - return scm_app_http.VcsHttpProxy( - echo_app_url, 'stub_path', 'stub_name', None) + return scm_app_http.VcsHttpProxy(echo_app_url, "stub_path", "stub_name", None) diff --git a/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py b/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py index 4d244bb6..ebc663d5 100644 --- a/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py +++ b/rhodecode/tests/lib/middleware/utils/test_wsgi_app_caller_client.py @@ -23,75 +23,72 @@ from rhodecode.lib.middleware.utils import wsgi_app_caller_client BASE_ENVIRON = { - 'REQUEST_METHOD': 'GET', - 'SERVER_NAME': 'localhost', - 'SERVER_PORT': '80', - 'SCRIPT_NAME': '', - 'PATH_INFO': '/', - 'QUERY_STRING': '', - 'foo.bool_var': True, - 'foo.str_var': 'True', - 'wsgi.foo': True, + "REQUEST_METHOD": "GET", + "SERVER_NAME": "localhost", + "SERVER_PORT": "80", + "SCRIPT_NAME": "", + "PATH_INFO": "/", + "QUERY_STRING": "", + "foo.bool_var": True, + "foo.str_var": "True", + "wsgi.foo": True, # Some non string values. The validator expects to get an iterable as # value. - (42,): '42', - (True,): 'False', + (42,): "42", + (True,): "False", } def assert_all_values_are_str(environ): """Checks that all values of a dict are str.""" for key, value in environ.items(): - assert isinstance(value, str), ( - "Value for key %s: has type %s but 'str' was expected. Value: %s" % - (key, type(value), repr(value))) + assert isinstance(value, str), "Value for key %s: has type %s but 'str' was expected. Value: %s" % ( + key, + type(value), + repr(value), + ) def assert_all_keys_are_str(environ): """Checks that all keys of a dict are str.""" for key, value in environ.items(): - assert isinstance(value, str), ( - "Key %s: has type %s but 'str' was expected. " % - (repr(key), type(key))) + assert isinstance(value, str), "Key %s: has type %s but 'str' was expected. " % (repr(key), type(key)) def assert_no_prefix_in_keys(environ, prefix): """Checks that no key of the dict starts with the prefix.""" for key in environ: - assert not key.startswith(prefix), 'Key %s should not be present' % key + assert not key.startswith(prefix), "Key %s should not be present" % key def test_get_environ(): clean_environ = wsgi_app_caller_client._get_clean_environ(BASE_ENVIRON) assert len(clean_environ) == 7 - assert_no_prefix_in_keys(clean_environ, 'wsgi.') + assert_no_prefix_in_keys(clean_environ, "wsgi.") assert_all_keys_are_str(clean_environ) assert_all_values_are_str(clean_environ) def test_remote_app_caller(): - class RemoteAppCallerMock(object): - - def handle(self, environ, input_data, arg1, arg2, - arg3=None, arg4=None, arg5=None): - assert ((arg1, arg2, arg3, arg4, arg5) == - ('a1', 'a2', 'a3', 'a4', None)) + def handle(self, environ, input_data, arg1, arg2, arg3=None, arg4=None, arg5=None): + assert (arg1, arg2, arg3, arg4, arg5) == ("a1", "a2", "a3", "a4", None) # Note: RemoteAppCaller is expected to return a tuple like the # following one - return ([b'content'], '200 OK', [('Content-Type', 'text/plain')]) + return ([b"content"], "200 OK", [("Content-Type", "text/plain")]) - wrapper_app = wsgi_app_caller_client.RemoteAppCaller( - RemoteAppCallerMock(), 'a1', 'a2', arg3='a3', arg4='a4') + wrapper_app = wsgi_app_caller_client.RemoteAppCaller(RemoteAppCallerMock(), "a1", "a2", arg3="a3", arg4="a4") test_app = CustomTestApp(wrapper_app) - response = test_app.get('/path') + response = test_app.get("/path") - assert response.status == '200 OK' - assert sorted(response.headers.items()) == sorted([ - ('Content-Type', 'text/plain'), - ('Content-Length', '7'), - ]) - assert response.text == 'content' + assert response.status == "200 OK" + assert sorted(response.headers.items()) == sorted( + [ + ("Content-Type", "text/plain"), + ("Content-Length", "7"), + ] + ) + assert response.text == "content" diff --git a/rhodecode/tests/lib/test_action_parser.py b/rhodecode/tests/lib/test_action_parser.py index bb567bae..cc3c6a6c 100644 --- a/rhodecode/tests/lib/test_action_parser.py +++ b/rhodecode/tests/lib/test_action_parser.py @@ -22,11 +22,9 @@ from rhodecode.lib.action_parser import ActionParser from rhodecode.model.db import UserLog -@pytest.mark.parametrize('pr_key', [ - 'user_commented_pull_request', - 'user_closed_pull_request', - 'user_merged_pull_request' -]) +@pytest.mark.parametrize( + "pr_key", ["user_commented_pull_request", "user_closed_pull_request", "user_merged_pull_request"] +) def test_action_map_pr_values(request_stub, baseapp, pr_key): parser = ActionParser(request_stub, UserLog(action="test:test")) assert pr_key in parser.action_map diff --git a/rhodecode/tests/lib/test_archive_caches.py b/rhodecode/tests/lib/test_archive_caches.py index 262f5624..55cfd071 100644 --- a/rhodecode/tests/lib/test_archive_caches.py +++ b/rhodecode/tests/lib/test_archive_caches.py @@ -27,10 +27,10 @@ from rhodecode.lib import archive_cache def file_reader(temp_store): - with open(temp_store, 'w') as f: + with open(temp_store, "w") as f: for cnt in range(10000): f.write(str(cnt)) - return open(temp_store, 'rb') + return open(temp_store, "rb") @pytest.fixture() @@ -40,9 +40,8 @@ def d_cache_instance(ini_settings): return d_cache -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestArchiveCaches(object): - def test_archivecache_empty_stats(self, d_cache_instance): d_cache = d_cache_instance shutil.rmtree(d_cache._directory) @@ -55,13 +54,12 @@ class TestArchiveCaches(object): shutil.rmtree(d_cache._directory) for n in range(100): - - archive_name = f'my-archive-abc-{n}.zip' + archive_name = f"my-archive-abc-{n}.zip" temp_archive_path = os.path.join(tmp_path, archive_name) - d_cache.store(archive_name, file_reader(temp_archive_path ), {'foo': 'bar'}) + d_cache.store(archive_name, file_reader(temp_archive_path), {"foo": "bar"}) reader, meta = d_cache.fetch(archive_name) content = reader.read() - assert content == open(temp_archive_path, 'rb').read() + assert content == open(temp_archive_path, "rb").read() stats = d_cache.get_statistics() assert (100, 3889000, {}) == stats @@ -71,10 +69,10 @@ class TestArchiveCaches(object): shutil.rmtree(d_cache._directory) n = 1 - archive_name = f'my-archive-abc-{n}.zip' + archive_name = f"my-archive-abc-{n}.zip" temp_archive_path = os.path.join(tmp_path, archive_name) - d_cache.store(archive_name, file_reader(temp_archive_path ), {'foo': 'bar'}) + d_cache.store(archive_name, file_reader(temp_archive_path), {"foo": "bar"}) stats = d_cache.get_statistics() assert (1, 38890, {}) == stats @@ -88,18 +86,16 @@ class TestArchiveCaches(object): shutil.rmtree(d_cache._directory) tries = 500 for n in range(tries): - - archive_name = f'my-archive-abc-{n}.zip' + archive_name = f"my-archive-abc-{n}.zip" temp_archive_path = os.path.join(tmp_path, archive_name) - d_cache.store(archive_name, file_reader(temp_archive_path ), {'foo': 'bar'}) + d_cache.store(archive_name, file_reader(temp_archive_path), {"foo": "bar"}) stats = d_cache.get_statistics() assert (tries, 19445000, {}) == stats evict_to = 0.005 # around (5mb) evicted_items = d_cache.evict(size_limit=d_cache.gb_to_bytes(evict_to)) evicted = 361 - assert {'removed_items': evicted, 'removed_size': 14039290} == evicted_items + assert {"removed_items": evicted, "removed_size": 14039290} == evicted_items stats = d_cache.get_statistics() assert (tries - evicted, 5405710, {}) == stats - diff --git a/rhodecode/tests/lib/test_audit_logger.py b/rhodecode/tests/lib/test_audit_logger.py index 0790c678..93ffa4ef 100644 --- a/rhodecode/tests/lib/test_audit_logger.py +++ b/rhodecode/tests/lib/test_audit_logger.py @@ -1,4 +1,4 @@ -import collections# Copyright (C) 2010-2024 RhodeCode GmbH +import collections # Copyright (C) 2010-2024 RhodeCode GmbH # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License, version 3 @@ -21,24 +21,33 @@ import pytest from rhodecode.lib import audit_logger -@pytest.mark.parametrize('store_type', [ - 'store_web', - 'store_api' -]) -@pytest.mark.parametrize('action, kwargs', [ - ('repo.edit', { - 'user': audit_logger.UserWrap(username='test-audit-log', ip_addr='8.8.8.8'), - 'action_data': {'data': {'hello': 'world'}} - }), - ('repo.edit', { - 'user': audit_logger.UserWrap(username=u'marcinkużmiń', ip_addr='8.8.8.8'), - 'action_data': {'data': {'hello': u'ąężą∑ęķ©'}} - }), - ('repo.edit', { - 'user': audit_logger.UserWrap(username='marcinkużmiń', ip_addr='8.8.8.8'), - 'action_data': {'data': {'hello': 'ąężą∑ęķ©'}} - }), -]) +@pytest.mark.parametrize("store_type", ["store_web", "store_api"]) +@pytest.mark.parametrize( + "action, kwargs", + [ + ( + "repo.edit", + { + "user": audit_logger.UserWrap(username="test-audit-log", ip_addr="8.8.8.8"), + "action_data": {"data": {"hello": "world"}}, + }, + ), + ( + "repo.edit", + { + "user": audit_logger.UserWrap(username="marcinkużmiń", ip_addr="8.8.8.8"), + "action_data": {"data": {"hello": "ąężą∑ęķ©"}}, + }, + ), + ( + "repo.edit", + { + "user": audit_logger.UserWrap(username="marcinkużmiń", ip_addr="8.8.8.8"), + "action_data": {"data": {"hello": "ąężą∑ęķ©"}}, + }, + ), + ], +) def test_store_audit_log(app, store_type, action, kwargs): store_action = getattr(audit_logger, store_type) store_action(action, **kwargs) diff --git a/rhodecode/tests/lib/test_auth.py b/rhodecode/tests/lib/test_auth.py index 1b8f98bc..707afbaf 100644 --- a/rhodecode/tests/lib/test_auth.py +++ b/rhodecode/tests/lib/test_auth.py @@ -33,275 +33,262 @@ from rhodecode.model.user_group import UserGroupModel def repickle(obj): import pickle + return pickle.loads(pickle.dumps(obj, protocol=pickle.HIGHEST_PROTOCOL)) def test_perm_origin_dict(): pod = auth.PermOriginDict() - pod['thing'] = 'read', 'default', 1 - assert pod['thing'] == 'read' + pod["thing"] = "read", "default", 1 + assert pod["thing"] == "read" + + assert pod.perm_origin_stack == {"thing": [("read", "default", 1)]} + + pod["thing"] = "write", "admin", 1 + assert pod["thing"] == "write" + + assert pod.perm_origin_stack == {"thing": [("read", "default", 1), ("write", "admin", 1)]} + + pod["other"] = "write", "default", 8 assert pod.perm_origin_stack == { - 'thing': [('read', 'default', 1)]} + "other": [("write", "default", 8)], + "thing": [("read", "default", 1), ("write", "admin", 1)], + } - pod['thing'] = 'write', 'admin', 1 - assert pod['thing'] == 'write' + pod["other"] = "none", "override", 8 assert pod.perm_origin_stack == { - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} - - pod['other'] = 'write', 'default', 8 - - assert pod.perm_origin_stack == { - 'other': [('write', 'default', 8)], - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} - - pod['other'] = 'none', 'override', 8 - - assert pod.perm_origin_stack == { - 'other': [('write', 'default', 8), ('none', 'override', 8)], - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} + "other": [("write", "default", 8), ("none", "override", 8)], + "thing": [("read", "default", 1), ("write", "admin", 1)], + } # we can still save regular key - pod['thing'] = 'read' + pod["thing"] = "read" with pytest.raises(ValueError): - pod['thing'] = 'read', 'missing-3td-key' + pod["thing"] = "read", "missing-3td-key" def test_perm_origin_dict_serialization(): pod = auth.PermOriginDict() - pod['thing'] = 'read', 'default', 1 + pod["thing"] = "read", "default", 1 - assert pod['thing'] == 'read' + assert pod["thing"] == "read" pod = repickle(pod) - assert pod['thing'] == 'read' + assert pod["thing"] == "read" - assert pod.perm_origin_stack == { - 'thing': [('read', 'default', 1)]} + assert pod.perm_origin_stack == {"thing": [("read", "default", 1)]} - pod['thing'] = 'write', 'admin', 1 - assert pod['thing'] == 'write' - assert pod['thing'] == 'write' - assert pod.perm_origin_stack == { - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} + pod["thing"] = "write", "admin", 1 + assert pod["thing"] == "write" + assert pod["thing"] == "write" + assert pod.perm_origin_stack == {"thing": [("read", "default", 1), ("write", "admin", 1)]} pod = repickle(pod) - assert pod['thing'] == 'write' - assert pod['thing'] == 'write' - assert pod.perm_origin_stack == { - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} + assert pod["thing"] == "write" + assert pod["thing"] == "write" + assert pod.perm_origin_stack == {"thing": [("read", "default", 1), ("write", "admin", 1)]} - pod['other'] = 'write', 'default', 8 + pod["other"] = "write", "default", 8 assert pod.perm_origin_stack == { - 'other': [('write', 'default', 8)], - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} + "other": [("write", "default", 8)], + "thing": [("read", "default", 1), ("write", "admin", 1)], + } pod = repickle(pod) assert pod.perm_origin_stack == { - 'other': [('write', 'default', 8)], - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} + "other": [("write", "default", 8)], + "thing": [("read", "default", 1), ("write", "admin", 1)], + } - pod['other'] = 'none', 'override', 8 + pod["other"] = "none", "override", 8 assert pod.perm_origin_stack == { - 'other': [('write', 'default', 8), ('none', 'override', 8)], - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} + "other": [("write", "default", 8), ("none", "override", 8)], + "thing": [("read", "default", 1), ("write", "admin", 1)], + } pod = repickle(pod) assert pod.perm_origin_stack == { - 'other': [('write', 'default', 8), ('none', 'override', 8)], - 'thing': [('read', 'default', 1), ('write', 'admin', 1)]} + "other": [("write", "default", 8), ("none", "override", 8)], + "thing": [("read", "default", 1), ("write", "admin", 1)], + } - pod['thing'] = 'read' + pod["thing"] = "read" with pytest.raises(ValueError): - pod['thing'] = 'read', 'missing-3td-key' + pod["thing"] = "read", "missing-3td-key" def test_branch_perm_origin_dict(): pod = auth.BranchPermOriginDict() - pod['resource'] = {'*pattern': 'read'}, 'default' - assert pod['resource'] == {'*pattern': 'read'} - assert pod.perm_origin_stack == {'resource': {'*pattern': [('read', 'default')]}} + pod["resource"] = {"*pattern": "read"}, "default" + assert pod["resource"] == {"*pattern": "read"} + assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default")]}} # 2nd call - pod['resource'] = {'*pattern': 'write'}, 'admin' - assert pod['resource'] == {'*pattern': 'write'} - assert pod.perm_origin_stack == {'resource': {'*pattern': [('read', 'default'), ('write', 'admin')]}} + pod["resource"] = {"*pattern": "write"}, "admin" + assert pod["resource"] == {"*pattern": "write"} + assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default"), ("write", "admin")]}} def test_branch_perm_origin_dict_serialization(): pod = auth.BranchPermOriginDict() - pod['resource'] = {'*pattern': 'read'}, 'default' - assert pod['resource'] == {'*pattern': 'read'} - assert pod.perm_origin_stack == {'resource': {'*pattern': [('read', 'default')]}} + pod["resource"] = {"*pattern": "read"}, "default" + assert pod["resource"] == {"*pattern": "read"} + assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default")]}} pod = repickle(pod) - assert pod['resource'] == {'*pattern': 'read'} - assert pod.perm_origin_stack == {'resource': {'*pattern': [('read', 'default')]}} + assert pod["resource"] == {"*pattern": "read"} + assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default")]}} # 2nd call - pod['resource'] = {'*pattern': 'write'}, 'admin' - assert pod['resource'] == {'*pattern': 'write'} - assert pod.perm_origin_stack == {'resource': {'*pattern': [('read', 'default'), ('write', 'admin')]}} + pod["resource"] = {"*pattern": "write"}, "admin" + assert pod["resource"] == {"*pattern": "write"} + assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default"), ("write", "admin")]}} pod = repickle(pod) - assert pod['resource'] == {'*pattern': 'write'} - assert pod.perm_origin_stack == {'resource': {'*pattern': [('read', 'default'), ('write', 'admin')]}} + assert pod["resource"] == {"*pattern": "write"} + assert pod.perm_origin_stack == {"resource": {"*pattern": [("read", "default"), ("write", "admin")]}} def test_cached_perms_data(user_regular, backend_random): permissions = get_permissions(user_regular) repo_name = backend_random.repo.repo_name - expected_global_permissions = { - 'repository.read', 'group.read', 'usergroup.read'} - assert expected_global_permissions.issubset(permissions['global']) - assert permissions['repositories'][repo_name] == 'repository.read' + expected_global_permissions = {"repository.read", "group.read", "usergroup.read"} + assert expected_global_permissions.issubset(permissions["global"]) + assert permissions["repositories"][repo_name] == "repository.read" def test_cached_perms_data_with_admin_user(user_regular, backend_random): permissions = get_permissions(user_regular, user_is_admin=True) repo_name = backend_random.repo.repo_name - assert 'hg.admin' in permissions['global'] - assert permissions['repositories'][repo_name] == 'repository.admin' + assert "hg.admin" in permissions["global"] + assert permissions["repositories"][repo_name] == "repository.admin" def test_cached_perms_data_with_admin_user_extended_calculation(user_regular, backend_random): - permissions = get_permissions(user_regular, user_is_admin=True, - calculate_super_admin=True) + permissions = get_permissions(user_regular, user_is_admin=True, calculate_super_admin=True) repo_name = backend_random.repo.repo_name - assert 'hg.admin' in permissions['global'] - assert permissions['repositories'][repo_name] == 'repository.admin' + assert "hg.admin" in permissions["global"] + assert permissions["repositories"][repo_name] == "repository.admin" def test_cached_perms_data_user_group_global_permissions(user_util): user, user_group = user_util.create_user_with_group() user_group.inherit_default_permissions = False - granted_permission = 'repository.write' + granted_permission = "repository.write" UserGroupModel().grant_perm(user_group, granted_permission) Session().commit() permissions = get_permissions(user) - assert granted_permission in permissions['global'] + assert granted_permission in permissions["global"] @pytest.mark.xfail(reason="Not implemented, see TODO note") def test_cached_perms_data_user_group_global_permissions_(user_util): user, user_group = user_util.create_user_with_group() - granted_permission = 'repository.write' + granted_permission = "repository.write" UserGroupModel().grant_perm(user_group, granted_permission) Session().commit() permissions = get_permissions(user) - assert granted_permission in permissions['global'] + assert granted_permission in permissions["global"] def test_cached_perms_data_user_global_permissions(user_util): user = user_util.create_user() - UserModel().grant_perm(user, 'repository.none') + UserModel().grant_perm(user, "repository.none") Session().commit() permissions = get_permissions(user, user_inherit_default_permissions=True) - assert 'repository.read' in permissions['global'] + assert "repository.read" in permissions["global"] -def test_cached_perms_data_repository_permissions_on_private_repository( - backend_random, user_util): +def test_cached_perms_data_repository_permissions_on_private_repository(backend_random, user_util): user, user_group = user_util.create_user_with_group() repo = backend_random.create_repo() repo.private = True - granted_permission = 'repository.write' - RepoModel().grant_user_group_permission( - repo, user_group.users_group_name, granted_permission) + granted_permission = "repository.write" + RepoModel().grant_user_group_permission(repo, user_group.users_group_name, granted_permission) Session().commit() permissions = get_permissions(user) - assert permissions['repositories'][repo.repo_name] == granted_permission + assert permissions["repositories"][repo.repo_name] == granted_permission -def test_cached_perms_data_repository_permissions_for_owner( - backend_random, user_util): +def test_cached_perms_data_repository_permissions_for_owner(backend_random, user_util): user = user_util.create_user() repo = backend_random.create_repo() repo.user_id = user.user_id permissions = get_permissions(user) - assert permissions['repositories'][repo.repo_name] == 'repository.admin' + assert permissions["repositories"][repo.repo_name] == "repository.admin" # TODO: johbo: Make cleanup in UserUtility smarter, then remove this hack repo.user_id = User.get_default_user_id() -def test_cached_perms_data_repository_permissions_not_inheriting_defaults( - backend_random, user_util): +def test_cached_perms_data_repository_permissions_not_inheriting_defaults(backend_random, user_util): user = user_util.create_user() repo = backend_random.create_repo() # Don't inherit default object permissions - UserModel().grant_perm(user, 'hg.inherit_default_perms.false') + UserModel().grant_perm(user, "hg.inherit_default_perms.false") Session().commit() permissions = get_permissions(user) - assert permissions['repositories'][repo.repo_name] == 'repository.none' + assert permissions["repositories"][repo.repo_name] == "repository.none" def test_cached_perms_data_default_permissions_on_repository_group(user_util): # Have a repository group with default permissions set repo_group = user_util.create_repo_group() default_user = User.get_default_user() - user_util.grant_user_permission_to_repo_group( - repo_group, default_user, 'repository.write') + user_util.grant_user_permission_to_repo_group(repo_group, default_user, "repository.write") user = user_util.create_user() permissions = get_permissions(user) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'repository.write' + assert permissions["repositories_groups"][repo_group.group_name] == "repository.write" -def test_cached_perms_data_default_permissions_on_repository_group_owner( - user_util): +def test_cached_perms_data_default_permissions_on_repository_group_owner(user_util): # Have a repository group repo_group = user_util.create_repo_group() default_user = User.get_default_user() # Add a permission for the default user to hit the code path - user_util.grant_user_permission_to_repo_group( - repo_group, default_user, 'repository.write') + user_util.grant_user_permission_to_repo_group(repo_group, default_user, "repository.write") # Have an owner of the group user = user_util.create_user() repo_group.user_id = user.user_id permissions = get_permissions(user) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.admin' + assert permissions["repositories_groups"][repo_group.group_name] == "group.admin" -def test_cached_perms_data_default_permissions_on_repository_group_no_inherit( - user_util): +def test_cached_perms_data_default_permissions_on_repository_group_no_inherit(user_util): # Have a repository group repo_group = user_util.create_repo_group() default_user = User.get_default_user() # Add a permission for the default user to hit the code path - user_util.grant_user_permission_to_repo_group( - repo_group, default_user, 'repository.write') + user_util.grant_user_permission_to_repo_group(repo_group, default_user, "repository.write") # Don't inherit default object permissions user = user_util.create_user() - UserModel().grant_perm(user, 'hg.inherit_default_perms.false') + UserModel().grant_perm(user, "hg.inherit_default_perms.false") Session().commit() permissions = get_permissions(user) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.none' + assert permissions["repositories_groups"][repo_group.group_name] == "group.none" -def test_cached_perms_data_repository_permissions_from_user_group( - user_util, backend_random): +def test_cached_perms_data_repository_permissions_from_user_group(user_util, backend_random): user, user_group = user_util.create_user_with_group() # Needs a second user group to make sure that we select the right @@ -311,69 +298,61 @@ def test_cached_perms_data_repository_permissions_from_user_group( repo = backend_random.create_repo() - RepoModel().grant_user_group_permission( - repo, user_group.users_group_name, 'repository.read') - RepoModel().grant_user_group_permission( - repo, user_group2.users_group_name, 'repository.write') + RepoModel().grant_user_group_permission(repo, user_group.users_group_name, "repository.read") + RepoModel().grant_user_group_permission(repo, user_group2.users_group_name, "repository.write") Session().commit() permissions = get_permissions(user) - assert permissions['repositories'][repo.repo_name] == 'repository.write' + assert permissions["repositories"][repo.repo_name] == "repository.write" -def test_cached_perms_data_repository_permissions_from_user_group_owner( - user_util, backend_random): +def test_cached_perms_data_repository_permissions_from_user_group_owner(user_util, backend_random): user, user_group = user_util.create_user_with_group() repo = backend_random.create_repo() repo.user_id = user.user_id - RepoModel().grant_user_group_permission( - repo, user_group.users_group_name, 'repository.write') + RepoModel().grant_user_group_permission(repo, user_group.users_group_name, "repository.write") Session().commit() permissions = get_permissions(user) - assert permissions['repositories'][repo.repo_name] == 'repository.admin' + assert permissions["repositories"][repo.repo_name] == "repository.admin" -def test_cached_perms_data_user_repository_permissions( - user_util, backend_random): +def test_cached_perms_data_user_repository_permissions(user_util, backend_random): user = user_util.create_user() repo = backend_random.create_repo() - granted_permission = 'repository.write' + granted_permission = "repository.write" RepoModel().grant_user_permission(repo, user, granted_permission) Session().commit() permissions = get_permissions(user) - assert permissions['repositories'][repo.repo_name] == granted_permission + assert permissions["repositories"][repo.repo_name] == granted_permission -def test_cached_perms_data_user_repository_permissions_explicit( - user_util, backend_random): +def test_cached_perms_data_user_repository_permissions_explicit(user_util, backend_random): user = user_util.create_user() repo = backend_random.create_repo() - granted_permission = 'repository.none' + granted_permission = "repository.none" RepoModel().grant_user_permission(repo, user, granted_permission) Session().commit() permissions = get_permissions(user, explicit=True) - assert permissions['repositories'][repo.repo_name] == granted_permission + assert permissions["repositories"][repo.repo_name] == granted_permission -def test_cached_perms_data_user_repository_permissions_owner( - user_util, backend_random): +def test_cached_perms_data_user_repository_permissions_owner(user_util, backend_random): user = user_util.create_user() repo = backend_random.create_repo() repo.user_id = user.user_id - RepoModel().grant_user_permission(repo, user, 'repository.write') + RepoModel().grant_user_permission(repo, user, "repository.write") Session().commit() permissions = get_permissions(user) - assert permissions['repositories'][repo.repo_name] == 'repository.admin' + assert permissions["repositories"][repo.repo_name] == "repository.admin" -def test_cached_perms_data_repository_groups_permissions_inherited( - user_util, backend_random): +def test_cached_perms_data_repository_groups_permissions_inherited(user_util, backend_random): user, user_group = user_util.create_user_with_group() # Needs a second group to hit the last condition @@ -382,249 +361,200 @@ def test_cached_perms_data_repository_groups_permissions_inherited( repo_group = user_util.create_repo_group() - user_util.grant_user_group_permission_to_repo_group( - repo_group, user_group, 'group.read') - user_util.grant_user_group_permission_to_repo_group( - repo_group, user_group2, 'group.write') + user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, "group.read") + user_util.grant_user_group_permission_to_repo_group(repo_group, user_group2, "group.write") permissions = get_permissions(user) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.write' + assert permissions["repositories_groups"][repo_group.group_name] == "group.write" -def test_cached_perms_data_repository_groups_permissions_inherited_owner( - user_util, backend_random): +def test_cached_perms_data_repository_groups_permissions_inherited_owner(user_util, backend_random): user, user_group = user_util.create_user_with_group() repo_group = user_util.create_repo_group() repo_group.user_id = user.user_id - granted_permission = 'group.write' - user_util.grant_user_group_permission_to_repo_group( - repo_group, user_group, granted_permission) + granted_permission = "group.write" + user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, granted_permission) permissions = get_permissions(user) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.admin' + assert permissions["repositories_groups"][repo_group.group_name] == "group.admin" -def test_cached_perms_data_repository_groups_permissions( - user_util, backend_random): +def test_cached_perms_data_repository_groups_permissions(user_util, backend_random): user = user_util.create_user() repo_group = user_util.create_repo_group() - granted_permission = 'group.write' - user_util.grant_user_permission_to_repo_group( - repo_group, user, granted_permission) + granted_permission = "group.write" + user_util.grant_user_permission_to_repo_group(repo_group, user, granted_permission) permissions = get_permissions(user) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.write' + assert permissions["repositories_groups"][repo_group.group_name] == "group.write" -def test_cached_perms_data_repository_groups_permissions_explicit( - user_util, backend_random): +def test_cached_perms_data_repository_groups_permissions_explicit(user_util, backend_random): user = user_util.create_user() repo_group = user_util.create_repo_group() - granted_permission = 'group.none' - user_util.grant_user_permission_to_repo_group( - repo_group, user, granted_permission) + granted_permission = "group.none" + user_util.grant_user_permission_to_repo_group(repo_group, user, granted_permission) permissions = get_permissions(user, explicit=True) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.none' + assert permissions["repositories_groups"][repo_group.group_name] == "group.none" -def test_cached_perms_data_repository_groups_permissions_owner( - user_util, backend_random): +def test_cached_perms_data_repository_groups_permissions_owner(user_util, backend_random): user = user_util.create_user() repo_group = user_util.create_repo_group() repo_group.user_id = user.user_id - granted_permission = 'group.write' - user_util.grant_user_permission_to_repo_group( - repo_group, user, granted_permission) + granted_permission = "group.write" + user_util.grant_user_permission_to_repo_group(repo_group, user, granted_permission) permissions = get_permissions(user) - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.admin' + assert permissions["repositories_groups"][repo_group.group_name] == "group.admin" -def test_cached_perms_data_user_group_permissions_inherited( - user_util, backend_random): +def test_cached_perms_data_user_group_permissions_inherited(user_util, backend_random): user, user_group = user_util.create_user_with_group() user_group2 = user_util.create_user_group() UserGroupModel().add_user_to_group(user_group2, user) target_user_group = user_util.create_user_group() - user_util.grant_user_group_permission_to_user_group( - target_user_group, user_group, 'usergroup.read') - user_util.grant_user_group_permission_to_user_group( - target_user_group, user_group2, 'usergroup.write') + user_util.grant_user_group_permission_to_user_group(target_user_group, user_group, "usergroup.read") + user_util.grant_user_group_permission_to_user_group(target_user_group, user_group2, "usergroup.write") permissions = get_permissions(user) - assert permissions['user_groups'][target_user_group.users_group_name] == \ - 'usergroup.write' + assert permissions["user_groups"][target_user_group.users_group_name] == "usergroup.write" -def test_cached_perms_data_user_group_permissions( - user_util, backend_random): +def test_cached_perms_data_user_group_permissions(user_util, backend_random): user = user_util.create_user() user_group = user_util.create_user_group() - UserGroupModel().grant_user_permission(user_group, user, 'usergroup.write') + UserGroupModel().grant_user_permission(user_group, user, "usergroup.write") Session().commit() permissions = get_permissions(user) - assert permissions['user_groups'][user_group.users_group_name] == \ - 'usergroup.write' + assert permissions["user_groups"][user_group.users_group_name] == "usergroup.write" -def test_cached_perms_data_user_group_permissions_explicit( - user_util, backend_random): +def test_cached_perms_data_user_group_permissions_explicit(user_util, backend_random): user = user_util.create_user() user_group = user_util.create_user_group() - UserGroupModel().grant_user_permission(user_group, user, 'usergroup.none') + UserGroupModel().grant_user_permission(user_group, user, "usergroup.none") Session().commit() permissions = get_permissions(user, explicit=True) - assert permissions['user_groups'][user_group.users_group_name] == \ - 'usergroup.none' + assert permissions["user_groups"][user_group.users_group_name] == "usergroup.none" -def test_cached_perms_data_user_group_permissions_not_inheriting_defaults( - user_util, backend_random): +def test_cached_perms_data_user_group_permissions_not_inheriting_defaults(user_util, backend_random): user = user_util.create_user() user_group = user_util.create_user_group() # Don't inherit default object permissions - UserModel().grant_perm(user, 'hg.inherit_default_perms.false') + UserModel().grant_perm(user, "hg.inherit_default_perms.false") Session().commit() permissions = get_permissions(user) - assert permissions['user_groups'][user_group.users_group_name] == \ - 'usergroup.none' + assert permissions["user_groups"][user_group.users_group_name] == "usergroup.none" -def test_permission_calculator_admin_permissions( - user_util, backend_random): +def test_permission_calculator_admin_permissions(user_util, backend_random): user = user_util.create_user() user_group = user_util.create_user_group() repo = backend_random.repo repo_group = user_util.create_repo_group() - calculator = auth.PermissionCalculator( - user.user_id, {}, False, False, True, 'higherwin') + calculator = auth.PermissionCalculator(user.user_id, {}, False, False, True, "higherwin") permissions = calculator._calculate_super_admin_permissions() - assert permissions['repositories_groups'][repo_group.group_name] == \ - 'group.admin' - assert permissions['user_groups'][user_group.users_group_name] == \ - 'usergroup.admin' - assert permissions['repositories'][repo.repo_name] == 'repository.admin' - assert 'hg.admin' in permissions['global'] + assert permissions["repositories_groups"][repo_group.group_name] == "group.admin" + assert permissions["user_groups"][user_group.users_group_name] == "usergroup.admin" + assert permissions["repositories"][repo.repo_name] == "repository.admin" + assert "hg.admin" in permissions["global"] -def test_permission_calculator_repository_permissions_robustness_from_group( - user_util, backend_random): +def test_permission_calculator_repository_permissions_robustness_from_group(user_util, backend_random): user, user_group = user_util.create_user_with_group() - RepoModel().grant_user_group_permission( - backend_random.repo, user_group.users_group_name, 'repository.write') + RepoModel().grant_user_group_permission(backend_random.repo, user_group.users_group_name, "repository.write") - calculator = auth.PermissionCalculator( - user.user_id, {}, False, False, False, 'higherwin') + calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin") calculator._calculate_repository_permissions() -def test_permission_calculator_repository_permissions_robustness_from_user( - user_util, backend_random): +def test_permission_calculator_repository_permissions_robustness_from_user(user_util, backend_random): user = user_util.create_user() - RepoModel().grant_user_permission( - backend_random.repo, user, 'repository.write') + RepoModel().grant_user_permission(backend_random.repo, user, "repository.write") Session().commit() - calculator = auth.PermissionCalculator( - user.user_id, {}, False, False, False, 'higherwin') + calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin") calculator._calculate_repository_permissions() -def test_permission_calculator_repo_group_permissions_robustness_from_group( - user_util, backend_random): +def test_permission_calculator_repo_group_permissions_robustness_from_group(user_util, backend_random): user, user_group = user_util.create_user_with_group() repo_group = user_util.create_repo_group() - user_util.grant_user_group_permission_to_repo_group( - repo_group, user_group, 'group.write') + user_util.grant_user_group_permission_to_repo_group(repo_group, user_group, "group.write") - calculator = auth.PermissionCalculator( - user.user_id, {}, False, False, False, 'higherwin') + calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin") calculator._calculate_repository_group_permissions() -def test_permission_calculator_repo_group_permissions_robustness_from_user( - user_util, backend_random): +def test_permission_calculator_repo_group_permissions_robustness_from_user(user_util, backend_random): user = user_util.create_user() repo_group = user_util.create_repo_group() - user_util.grant_user_permission_to_repo_group( - repo_group, user, 'group.write') + user_util.grant_user_permission_to_repo_group(repo_group, user, "group.write") - calculator = auth.PermissionCalculator( - user.user_id, {}, False, False, False, 'higherwin') + calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin") calculator._calculate_repository_group_permissions() -def test_permission_calculator_user_group_permissions_robustness_from_group( - user_util, backend_random): +def test_permission_calculator_user_group_permissions_robustness_from_group(user_util, backend_random): user, user_group = user_util.create_user_with_group() target_user_group = user_util.create_user_group() - user_util.grant_user_group_permission_to_user_group( - target_user_group, user_group, 'usergroup.write') + user_util.grant_user_group_permission_to_user_group(target_user_group, user_group, "usergroup.write") - calculator = auth.PermissionCalculator( - user.user_id, {}, False, False, False, 'higherwin') + calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin") calculator._calculate_user_group_permissions() -def test_permission_calculator_user_group_permissions_robustness_from_user( - user_util, backend_random): +def test_permission_calculator_user_group_permissions_robustness_from_user(user_util, backend_random): user = user_util.create_user() target_user_group = user_util.create_user_group() - user_util.grant_user_permission_to_user_group( - target_user_group, user, 'usergroup.write') + user_util.grant_user_permission_to_user_group(target_user_group, user, "usergroup.write") - calculator = auth.PermissionCalculator( - user.user_id, {}, False, False, False, 'higherwin') + calculator = auth.PermissionCalculator(user.user_id, {}, False, False, False, "higherwin") calculator._calculate_user_group_permissions() -@pytest.mark.parametrize("algo, new_permission, old_permission, expected", [ - ('higherwin', 'repository.none', 'repository.none', 'repository.none'), - ('higherwin', 'repository.read', 'repository.none', 'repository.read'), - ('lowerwin', 'repository.write', 'repository.write', 'repository.write'), - ('lowerwin', 'repository.read', 'repository.write', 'repository.read'), -]) -def test_permission_calculator_choose_permission( - user_regular, algo, new_permission, old_permission, expected): - calculator = auth.PermissionCalculator( - user_regular.user_id, {}, False, False, False, algo) +@pytest.mark.parametrize( + "algo, new_permission, old_permission, expected", + [ + ("higherwin", "repository.none", "repository.none", "repository.none"), + ("higherwin", "repository.read", "repository.none", "repository.read"), + ("lowerwin", "repository.write", "repository.write", "repository.write"), + ("lowerwin", "repository.read", "repository.write", "repository.read"), + ], +) +def test_permission_calculator_choose_permission(user_regular, algo, new_permission, old_permission, expected): + calculator = auth.PermissionCalculator(user_regular.user_id, {}, False, False, False, algo) result = calculator._choose_permission(new_permission, old_permission) assert result == expected -def test_permission_calculator_choose_permission_raises_on_wrong_algo( - user_regular): - calculator = auth.PermissionCalculator( - user_regular.user_id, {}, False, False, False, 'invalid') - result = calculator._choose_permission( - 'repository.read', 'repository.read') +def test_permission_calculator_choose_permission_raises_on_wrong_algo(user_regular): + calculator = auth.PermissionCalculator(user_regular.user_id, {}, False, False, False, "invalid") + result = calculator._choose_permission("repository.read", "repository.read") # TODO: johbo: This documents the existing behavior. Think of an # improvement. assert result is None @@ -634,10 +564,10 @@ def test_auth_user_get_cookie_store_for_normal_user(user_util): user = user_util.create_user() auth_user = auth.AuthUser(user_id=user.user_id) expected_data = { - 'username': user.username, - 'user_id': user.user_id, - 'password': md5_safe(user.password), - 'is_authenticated': False + "username": user.username, + "user_id": user.user_id, + "password": md5_safe(user.password), + "is_authenticated": False, } assert auth_user.get_cookie_store() == expected_data @@ -646,10 +576,10 @@ def test_auth_user_get_cookie_store_for_default_user(): default_user = User.get_default_user() auth_user = auth.AuthUser() expected_data = { - 'username': User.DEFAULT_USER, - 'user_id': default_user.user_id, - 'password': md5_safe(default_user.password), - 'is_authenticated': True + "username": User.DEFAULT_USER, + "user_id": default_user.user_id, + "password": md5_safe(default_user.password), + "is_authenticated": True, } assert auth_user.get_cookie_store() == expected_data @@ -661,13 +591,13 @@ def get_permissions(user, **kwargs): Fill in `**kwargs` if specific values are needed for a test. """ call_args = { - 'user_id': user.user_id, - 'scope': {}, - 'user_is_admin': False, - 'user_inherit_default_permissions': False, - 'explicit': False, - 'algo': 'higherwin', - 'calculate_super_admin': False, + "user_id": user.user_id, + "scope": {}, + "user_is_admin": False, + "user_inherit_default_permissions": False, + "explicit": False, + "algo": "higherwin", + "calculate_super_admin": False, } call_args.update(kwargs) permissions = auth._cached_perms_data(**call_args) @@ -676,16 +606,16 @@ def get_permissions(user, **kwargs): class TestGenerateAuthToken(object): def test_salt_is_used_when_specified(self): - salt = b'abcde' - user_name = 'test_user' + salt = b"abcde" + user_name = "test_user" result = auth.generate_auth_token(user_name, salt) expected_result = sha1(safe_bytes(user_name) + salt) assert result == expected_result def test_salt_is_geneated_when_not_specified(self): - user_name = 'test_user' + user_name = "test_user" random_salt = os.urandom(16) - with patch.object(auth, 'os') as os_mock: + with patch.object(auth, "os") as os_mock: os_mock.urandom.return_value = random_salt result = auth.generate_auth_token(user_name) @@ -693,26 +623,39 @@ class TestGenerateAuthToken(object): assert result == expected_result -@pytest.mark.parametrize("test_token, test_roles, auth_result, expected_tokens", [ - ('', None, False, - []), - ('wrongtoken', None, False, - []), - ('abracadabra_vcs', [AuthTokenModel.cls.ROLE_API], False, - [('abracadabra_api', AuthTokenModel.cls.ROLE_API, -1)]), - ('abracadabra_api', [AuthTokenModel.cls.ROLE_API], True, - [('abracadabra_api', AuthTokenModel.cls.ROLE_API, -1)]), - ('abracadabra_api', [AuthTokenModel.cls.ROLE_API], True, - [('abracadabra_api', AuthTokenModel.cls.ROLE_API, -1), - ('abracadabra_http', AuthTokenModel.cls.ROLE_HTTP, -1)]), -]) -def test_auth_by_token(test_token, test_roles, auth_result, expected_tokens, - user_util): +@pytest.mark.parametrize( + "test_token, test_roles, auth_result, expected_tokens", + [ + ("", None, False, []), + ("wrongtoken", None, False, []), + ( + "abracadabra_vcs", + [AuthTokenModel.cls.ROLE_API], + False, + [("abracadabra_api", AuthTokenModel.cls.ROLE_API, -1)], + ), + ( + "abracadabra_api", + [AuthTokenModel.cls.ROLE_API], + True, + [("abracadabra_api", AuthTokenModel.cls.ROLE_API, -1)], + ), + ( + "abracadabra_api", + [AuthTokenModel.cls.ROLE_API], + True, + [ + ("abracadabra_api", AuthTokenModel.cls.ROLE_API, -1), + ("abracadabra_http", AuthTokenModel.cls.ROLE_HTTP, -1), + ], + ), + ], +) +def test_auth_by_token(test_token, test_roles, auth_result, expected_tokens, user_util): user = user_util.create_user() user_id = user.user_id for token, role, expires in expected_tokens: - new_token = AuthTokenModel().create(user_id, u'test-token', expires, role) + new_token = AuthTokenModel().create(user_id, "test-token", expires, role) new_token.api_key = token # inject known name for testing... - assert auth_result == user.authenticate_by_token( - test_token, roles=test_roles) + assert auth_result == user.authenticate_by_token(test_token, roles=test_roles) diff --git a/rhodecode/tests/lib/test_auth_crypto_backend.py b/rhodecode/tests/lib/test_auth_crypto_backend.py index f85f1506..1066d8d2 100644 --- a/rhodecode/tests/lib/test_auth_crypto_backend.py +++ b/rhodecode/tests/lib/test_auth_crypto_backend.py @@ -19,6 +19,7 @@ """ Tests checking the crypto backends which can be used by lib/auth. """ + import collections import pytest @@ -28,6 +29,7 @@ from rhodecode.lib import auth # Utility functions to get or check passwords + def test_get_crypt_password_accepts_unicode(password): result = auth.get_crypt_password(password.value) assert result == password.hashed @@ -40,6 +42,7 @@ def test_check_password_accepts_unicode(password): # API contracts from _RhodeCodeCryptoBase + def test_constructor_takes_no_arguments(crypto_backend_class): instance = crypto_backend_class() assert instance @@ -61,22 +64,24 @@ def test_hash_create_enforces_bytes(crypto_backend, password): def test_hash_check(crypto_backend, password): - not_matching = 'stub-hash' + not_matching = "stub-hash" with pytest.raises(TypeError): crypto_backend.hash_check(password.value, not_matching) def test_hash_check_with_update_enforces_bytes(crypto_backend, password): - not_matching = 'stub-hash' + not_matching = "stub-hash" with pytest.raises(TypeError): crypto_backend.hash_check_with_upgrade(password.value, not_matching) -@pytest.fixture(params=[ - auth._RhodeCodeCryptoTest, - auth._RhodeCodeCryptoBCrypt, - auth._RhodeCodeCryptoSha256, -]) +@pytest.fixture( + params=[ + auth._RhodeCodeCryptoTest, + auth._RhodeCodeCryptoBCrypt, + auth._RhodeCodeCryptoSha256, + ] +) def crypto_backend_class(request): """ Parameterizes per crypto backend class. @@ -91,9 +96,8 @@ def crypto_backend(crypto_backend_class): @pytest.fixture() def password(): - encoding = 'utf-8' - value = u'value' + encoding = "utf-8" + value = "value" value_encoded = value.encode(encoding) value_hashed = auth.crypto_backend().hash_create(value_encoded) - return collections.namedtuple('Password', 'value, encoded, hashed')( - value, value_encoded, value_hashed) + return collections.namedtuple("Password", "value, encoded, hashed")(value, value_encoded, value_hashed) diff --git a/rhodecode/tests/lib/test_base.py b/rhodecode/tests/lib/test_base.py index e5ccedbb..0d5fc0ad 100644 --- a/rhodecode/tests/lib/test_base.py +++ b/rhodecode/tests/lib/test_base.py @@ -23,28 +23,31 @@ from rhodecode.lib import base from rhodecode.model import db -@pytest.mark.parametrize('result_key, expected_value', [ - ('username', 'stub_username'), - ('action', 'stub_action'), - ('repository', 'stub_repo_name'), - ('scm', 'stub_scm'), - ('hooks', ['stub_hook']), - ('config', 'stub_ini_filename'), - ('ip', '1.2.3.4'), - ('server_url', 'https://example.com'), - ('user_agent', 'client-text-v1.1'), - # TODO: johbo: Commpare locking parameters with `_get_rc_scm_extras` - # in hooks_utils. - ('make_lock', None), - ('locked_by', [None, None, None]), -]) +@pytest.mark.parametrize( + "result_key, expected_value", + [ + ("username", "stub_username"), + ("action", "stub_action"), + ("repository", "stub_repo_name"), + ("scm", "stub_scm"), + ("hooks", ["stub_hook"]), + ("config", "stub_ini_filename"), + ("ip", "1.2.3.4"), + ("server_url", "https://example.com"), + ("user_agent", "client-text-v1.1"), + # TODO: johbo: Commpare locking parameters with `_get_rc_scm_extras` + # in hooks_utils. + ("make_lock", None), + ("locked_by", [None, None, None]), + ], +) def test_vcs_operation_context_parameters(result_key, expected_value): result = call_vcs_operation_context() assert result[result_key] == expected_value -@patch('rhodecode.model.db.User.get_by_username', Mock()) -@patch('rhodecode.model.db.Repository.get_by_repo_name') +@patch("rhodecode.model.db.User.get_by_username", Mock()) +@patch("rhodecode.model.db.Repository.get_by_repo_name") def test_vcs_operation_context_checks_locking(mock_get_by_repo_name): mock_get_locking_state = mock_get_by_repo_name().get_locking_state mock_get_locking_state.return_value = (None, None, [None, None, None]) @@ -52,43 +55,35 @@ def test_vcs_operation_context_checks_locking(mock_get_by_repo_name): assert mock_get_locking_state.called -@patch('rhodecode.model.db.Repository.get_locking_state') -def test_vcs_operation_context_skips_locking_checks_if_anonymouse( - mock_get_locking_state): - call_vcs_operation_context( - username=db.User.DEFAULT_USER, check_locking=True) +@patch("rhodecode.model.db.Repository.get_locking_state") +def test_vcs_operation_context_skips_locking_checks_if_anonymouse(mock_get_locking_state): + call_vcs_operation_context(username=db.User.DEFAULT_USER, check_locking=True) assert not mock_get_locking_state.called -@patch('rhodecode.model.db.Repository.get_locking_state') +@patch("rhodecode.model.db.Repository.get_locking_state") def test_vcs_operation_context_can_skip_locking_check(mock_get_locking_state): call_vcs_operation_context(check_locking=False) assert not mock_get_locking_state.called -@patch.object( - base, 'get_enabled_hook_classes', Mock(return_value=['stub_hook'])) -@patch('rhodecode.lib.utils2.get_server_url', - Mock(return_value='https://example.com')) -@patch.object(db.User, 'get_by_username', - Mock(return_value=Mock(return_value=1))) +@patch.object(base, "get_enabled_hook_classes", Mock(return_value=["stub_hook"])) +@patch("rhodecode.lib.utils2.get_server_url", Mock(return_value="https://example.com")) +@patch.object(db.User, "get_by_username", Mock(return_value=Mock(return_value=1))) def call_vcs_operation_context(**kwargs_override): kwargs = { - 'repo_name': 'stub_repo_name', - 'username': 'stub_username', - 'action': 'stub_action', - 'scm': 'stub_scm', - 'check_locking': False, + "repo_name": "stub_repo_name", + "username": "stub_username", + "action": "stub_action", + "scm": "stub_scm", + "check_locking": False, } kwargs.update(kwargs_override) - config_file_patch = patch.dict( - 'rhodecode.CONFIG', {'__file__': 'stub_ini_filename'}) - settings_patch = patch.object(base, 'VcsSettingsModel') + config_file_patch = patch.dict("rhodecode.CONFIG", {"__file__": "stub_ini_filename"}) + settings_patch = patch.object(base, "VcsSettingsModel") with config_file_patch, settings_patch as settings_mock: result = base.vcs_operation_context( - environ={'HTTP_USER_AGENT': 'client-text-v1.1', - 'REMOTE_ADDR': '1.2.3.4'}, **kwargs) - settings_mock.assert_called_once_with(repo='stub_repo_name') + environ={"HTTP_USER_AGENT": "client-text-v1.1", "REMOTE_ADDR": "1.2.3.4"}, **kwargs + ) + settings_mock.assert_called_once_with(repo="stub_repo_name") return result - - diff --git a/rhodecode/tests/lib/test_caches.py b/rhodecode/tests/lib/test_caches.py index 018d4bf4..67245605 100644 --- a/rhodecode/tests/lib/test_caches.py +++ b/rhodecode/tests/lib/test_caches.py @@ -23,53 +23,61 @@ import pytest from rhodecode.lib import rc_cache -@pytest.mark.usefixtures('app') +@pytest.mark.usefixtures("app") class TestCaches(object): - def test_cache_decorator_init_not_configured(self): with pytest.raises(EnvironmentError): - rc_cache.get_or_create_region('dontexist') + rc_cache.get_or_create_region("dontexist") - @pytest.mark.parametrize('region_name', [ - 'cache_perms', u'cache_perms', - ]) + @pytest.mark.parametrize( + "region_name", + [ + "cache_perms", + "cache_perms", + ], + ) def test_cache_decorator_init(self, region_name): namespace = region_name cache_region = rc_cache.get_or_create_region(region_name, region_namespace=namespace) assert cache_region - @pytest.mark.parametrize('example_input', [ - ('',), - (u'/ac',), - (u'/ac', 1, 2, object()), - (u'/ęćc', 1, 2, object()), - ('/ąac',), - (u'/ac', ), - ]) + @pytest.mark.parametrize( + "example_input", + [ + ("",), + ("/ac",), + ("/ac", 1, 2, object()), + ("/ęćc", 1, 2, object()), + ("/ąac",), + ("/ac",), + ], + ) def test_cache_manager_create_key(self, example_input): key = rc_cache.utils.compute_key_from_params(*example_input) assert key - @pytest.mark.parametrize('example_namespace', [ - 'namespace', None - ]) - @pytest.mark.parametrize('example_input', [ - ('',), - (u'/ac',), - (u'/ac', 1, 2, object()), - (u'/ęćc', 1, 2, object()), - ('/ąac',), - (u'/ac', ), - ]) + @pytest.mark.parametrize("example_namespace", ["namespace", None]) + @pytest.mark.parametrize( + "example_input", + [ + ("",), + ("/ac",), + ("/ac", 1, 2, object()), + ("/ęćc", 1, 2, object()), + ("/ąac",), + ("/ac",), + ], + ) def test_cache_keygen(self, example_input, example_namespace): def func_wrapped(): return 1 + func = rc_cache.utils.custom_key_generator(None, example_namespace, func_wrapped) key = func(*example_input) assert key def test_store_value_in_cache(self): - cache_region = rc_cache.get_or_create_region('cache_perms', 'test_cache') + cache_region = rc_cache.get_or_create_region("cache_perms", "test_cache") # make sure we empty the cache now cache_region.delete_multi(cache_region.backend.list_keys()) @@ -85,7 +93,7 @@ class TestCaches(object): assert len(set(cache_region.backend.list_keys())) == 10 def test_store_and_get_value_from_region(self): - cache_region = rc_cache.get_or_create_region('cache_perms', 'test_cache') + cache_region = rc_cache.get_or_create_region("cache_perms", "test_cache") # make sure we empty the cache now for key in cache_region.backend.list_keys(): cache_region.delete(key) @@ -97,7 +105,7 @@ class TestCaches(object): result = set() for x in range(10): - ret = compute('x') + ret = compute("x") result.add(ret) # once computed we have only one value (the same from cache) diff --git a/rhodecode/tests/lib/test_codeblocks.py b/rhodecode/tests/lib/test_codeblocks.py index b191b437..17c85db5 100644 --- a/rhodecode/tests/lib/test_codeblocks.py +++ b/rhodecode/tests/lib/test_codeblocks.py @@ -20,315 +20,347 @@ import pytest from pygments.lexers import get_lexer_by_name from rhodecode.tests import no_newline_id_generator -from rhodecode.lib.codeblocks import ( - tokenize_string, split_token_stream, rollup_tokenstream, - render_tokenstream) +from rhodecode.lib.codeblocks import tokenize_string, split_token_stream, rollup_tokenstream, render_tokenstream class TestTokenizeString(object): - - python_code = ''' + python_code = """ import this var = 6 print("this") - ''' + """ def test_tokenize_as_python(self): - lexer = get_lexer_by_name('python') + lexer = get_lexer_by_name("python") tokens = list(tokenize_string(self.python_code, lexer)) expected_tokens = [ - ('w', '\n'), - ('', ' '), - ('kn', 'import'), - ('', ' '), - ('nn', 'this'), - ('w', '\n'), - ('w', '\n'), - ('', ' '), - ('n', 'var'), - ('', ' '), - ('o', '='), - ('', ' '), - ('mi', '6'), - ('w', '\n'), - ('', ' '), - ('nb', 'print'), - ('p', '('), - ('s2', '"'), - ('s2', 'this'), - ('s2', '"'), - ('p', ')'), - ('w', '\n'), - ('w', '\n'), - ('', ' ') + ("w", "\n"), + ("", " "), + ("kn", "import"), + ("", " "), + ("nn", "this"), + ("w", "\n"), + ("w", "\n"), + ("", " "), + ("n", "var"), + ("", " "), + ("o", "="), + ("", " "), + ("mi", "6"), + ("w", "\n"), + ("", " "), + ("nb", "print"), + ("p", "("), + ("s2", '"'), + ("s2", "this"), + ("s2", '"'), + ("p", ")"), + ("w", "\n"), + ("w", "\n"), + ("", " "), ] assert tokens == expected_tokens def test_tokenize_as_text(self): - lexer = get_lexer_by_name('text') + lexer = get_lexer_by_name("text") tokens = list(tokenize_string(self.python_code, lexer)) - assert tokens == [ - ('', - '\n import this\n\n var = 6\n print("this")\n\n ') - ] + assert tokens == [("", '\n import this\n\n var = 6\n print("this")\n\n ')] class TestSplitTokenStream(object): - def test_split_token_stream(self): - tokens = [('type1', 'some\ntext'), ('type2', 'more\n')] + tokens = [("type1", "some\ntext"), ("type2", "more\n")] content = [x + y for x, y in tokens] lines = list(split_token_stream(tokens, content)) assert lines == [ - [('type1', 'some')], - [('type1', 'text'), ('type2', 'more')], - [('type2', '')], + [("type1", "some")], + [("type1", "text"), ("type2", "more")], + [("type2", "")], ] def test_split_token_stream_single(self): - tokens = [('type1', '\n')] + tokens = [("type1", "\n")] content = [x + y for x, y in tokens] lines = list(split_token_stream(tokens, content)) assert lines == [ - [('type1', '')], - [('type1', '')], + [("type1", "")], + [("type1", "")], ] def test_split_token_stream_single_repeat(self): - tokens = [('type1', '\n\n\n')] + tokens = [("type1", "\n\n\n")] content = [x + y for x, y in tokens] lines = list(split_token_stream(tokens, content)) assert lines == [ - [('type1', '')], - [('type1', '')], - [('type1', '')], - [('type1', '')], + [("type1", "")], + [("type1", "")], + [("type1", "")], + [("type1", "")], ] def test_split_token_stream_multiple_repeat(self): - tokens = [('type1', '\n\n'), ('type2', '\n\n')] + tokens = [("type1", "\n\n"), ("type2", "\n\n")] content = [x + y for x, y in tokens] lines = list(split_token_stream(tokens, content)) assert lines == [ - [('type1', '')], - [('type1', '')], - [('type1', ''), ('type2', '')], - [('type2', '')], - [('type2', '')], + [("type1", "")], + [("type1", "")], + [("type1", ""), ("type2", "")], + [("type2", "")], + [("type2", "")], ] def test_no_tokens_by_content(self): tokens = [] - content = '\ufeff' + content = "\ufeff" lines = list(split_token_stream(tokens, content)) assert lines == [ - [('', content)], + [("", content)], ] def test_no_tokens_by_valid_content(self): from pygments.lexers.css import CssLexer - content = '\ufeff table.dataTable' + + content = "\ufeff table.dataTable" tokens = tokenize_string(content, CssLexer()) lines = list(split_token_stream(tokens, content)) assert lines == [ - [('w', ' '), - ('nt', 'table'), - ('p', '.'), - ('nc', 'dataTable')], + [("w", " "), ("nt", "table"), ("p", "."), ("nc", "dataTable")], ] class TestRollupTokens(object): - - @pytest.mark.parametrize('tokenstream,output', [ - ([], - []), - ([('A', 'hell'), ('A', 'o')], [ - ('A', [ - ('', 'hello')]), - ]), - ([('A', 'hell'), ('B', 'o')], [ - ('A', [ - ('', 'hell')]), - ('B', [ - ('', 'o')]), - ]), - ([('A', 'hel'), ('A', 'lo'), ('B', ' '), ('A', 'there')], [ - ('A', [ - ('', 'hello')]), - ('B', [ - ('', ' ')]), - ('A', [ - ('', 'there')]), - ]), - ]) + @pytest.mark.parametrize( + "tokenstream,output", + [ + ([], []), + ( + [("A", "hell"), ("A", "o")], + [ + ("A", [("", "hello")]), + ], + ), + ( + [("A", "hell"), ("B", "o")], + [ + ("A", [("", "hell")]), + ("B", [("", "o")]), + ], + ), + ( + [("A", "hel"), ("A", "lo"), ("B", " "), ("A", "there")], + [ + ("A", [("", "hello")]), + ("B", [("", " ")]), + ("A", [("", "there")]), + ], + ), + ], + ) def test_rollup_tokenstream_without_ops(self, tokenstream, output): assert list(rollup_tokenstream(tokenstream)) == output - @pytest.mark.parametrize('tokenstream,output', [ - ([], - []), - ([('A', '', 'hell'), ('A', '', 'o')], [ - ('A', [ - ('', 'hello')]), - ]), - ([('A', '', 'hell'), ('B', '', 'o')], [ - ('A', [ - ('', 'hell')]), - ('B', [ - ('', 'o')]), - ]), - ([('A', '', 'h'), ('B', '', 'e'), ('C', '', 'y')], [ - ('A', [ - ('', 'h')]), - ('B', [ - ('', 'e')]), - ('C', [ - ('', 'y')]), - ]), - ([('A', '', 'h'), ('A', '', 'e'), ('C', '', 'y')], [ - ('A', [ - ('', 'he')]), - ('C', [ - ('', 'y')]), - ]), - ([('A', 'ins', 'h'), ('A', 'ins', 'e')], [ - ('A', [ - ('ins', 'he') - ]), - ]), - ([('A', 'ins', 'h'), ('A', 'del', 'e')], [ - ('A', [ - ('ins', 'h'), - ('del', 'e') - ]), - ]), - ([('A', 'ins', 'h'), ('B', 'del', 'e'), ('B', 'del', 'y')], [ - ('A', [ - ('ins', 'h'), - ]), - ('B', [ - ('del', 'ey'), - ]), - ]), - ([('A', 'ins', 'h'), ('A', 'del', 'e'), ('B', 'del', 'y')], [ - ('A', [ - ('ins', 'h'), - ('del', 'e'), - ]), - ('B', [ - ('del', 'y'), - ]), - ]), - ([('A', '', 'some'), ('A', 'ins', 'new'), ('A', '', 'name')], [ - ('A', [ - ('', 'some'), - ('ins', 'new'), - ('', 'name'), - ]), - ]), - ]) + @pytest.mark.parametrize( + "tokenstream,output", + [ + ([], []), + ( + [("A", "", "hell"), ("A", "", "o")], + [ + ("A", [("", "hello")]), + ], + ), + ( + [("A", "", "hell"), ("B", "", "o")], + [ + ("A", [("", "hell")]), + ("B", [("", "o")]), + ], + ), + ( + [("A", "", "h"), ("B", "", "e"), ("C", "", "y")], + [ + ("A", [("", "h")]), + ("B", [("", "e")]), + ("C", [("", "y")]), + ], + ), + ( + [("A", "", "h"), ("A", "", "e"), ("C", "", "y")], + [ + ("A", [("", "he")]), + ("C", [("", "y")]), + ], + ), + ( + [("A", "ins", "h"), ("A", "ins", "e")], + [ + ("A", [("ins", "he")]), + ], + ), + ( + [("A", "ins", "h"), ("A", "del", "e")], + [ + ("A", [("ins", "h"), ("del", "e")]), + ], + ), + ( + [("A", "ins", "h"), ("B", "del", "e"), ("B", "del", "y")], + [ + ( + "A", + [ + ("ins", "h"), + ], + ), + ( + "B", + [ + ("del", "ey"), + ], + ), + ], + ), + ( + [("A", "ins", "h"), ("A", "del", "e"), ("B", "del", "y")], + [ + ( + "A", + [ + ("ins", "h"), + ("del", "e"), + ], + ), + ( + "B", + [ + ("del", "y"), + ], + ), + ], + ), + ( + [("A", "", "some"), ("A", "ins", "new"), ("A", "", "name")], + [ + ( + "A", + [ + ("", "some"), + ("ins", "new"), + ("", "name"), + ], + ), + ], + ), + ], + ) def test_rollup_tokenstream_with_ops(self, tokenstream, output): assert list(rollup_tokenstream(tokenstream)) == output class TestRenderTokenStream(object): - - @pytest.mark.parametrize('tokenstream,output', [ - ( - [], - '', - ), - ( - [('', '', '')], - '', - ), - ( - [('', '', 'text')], - 'text', - ), - ( - [('A', '', '')], - '', - ), - ( - [('A', '', 'hello')], - 'hello', - ), - ( - [('A', '', 'hel'), ('A', '', 'lo')], - 'hello', - ), - ( - [('A', '', 'two\n'), ('A', '', 'lines')], - 'two\nlines', - ), - ( - [('A', '', '\nthree\n'), ('A', '', 'lines')], - '\nthree\nlines', - ), - ( - [('', '', '\n'), ('A', '', 'line')], - '\nline', - ), - ( - [('', 'ins', '\n'), ('A', '', 'line')], - '\nline', - ), - ( - [('A', '', 'hel'), ('A', 'ins', 'lo')], - 'hello', - ), - ( - [('A', '', 'hel'), ('A', 'ins', 'l'), ('A', 'ins', 'o')], - 'hello', - ), - ( - [('A', '', 'hel'), ('A', 'ins', 'l'), ('A', 'del', 'o')], - 'hello', - ), - ( - [('A', '', 'hel'), ('B', '', 'lo')], - 'hello', - ), - ( - [('A', '', 'hel'), ('B', 'ins', 'lo')], - 'hello', - ), - ], ids=no_newline_id_generator) + @pytest.mark.parametrize( + "tokenstream,output", + [ + ( + [], + "", + ), + ( + [("", "", "")], + "", + ), + ( + [("", "", "text")], + "text", + ), + ( + [("A", "", "")], + '', + ), + ( + [("A", "", "hello")], + 'hello', + ), + ( + [("A", "", "hel"), ("A", "", "lo")], + 'hello', + ), + ( + [("A", "", "two\n"), ("A", "", "lines")], + 'two\nlines', + ), + ( + [("A", "", "\nthree\n"), ("A", "", "lines")], + '\nthree\nlines', + ), + ( + [("", "", "\n"), ("A", "", "line")], + '\nline', + ), + ( + [("", "ins", "\n"), ("A", "", "line")], + '\nline', + ), + ( + [("A", "", "hel"), ("A", "ins", "lo")], + 'hello', + ), + ( + [("A", "", "hel"), ("A", "ins", "l"), ("A", "ins", "o")], + 'hello', + ), + ( + [("A", "", "hel"), ("A", "ins", "l"), ("A", "del", "o")], + 'hello', + ), + ( + [("A", "", "hel"), ("B", "", "lo")], + 'hello', + ), + ( + [("A", "", "hel"), ("B", "ins", "lo")], + 'hello', + ), + ], + ids=no_newline_id_generator, + ) def test_render_tokenstream_with_ops(self, tokenstream, output): html = render_tokenstream(tokenstream) assert html == output - @pytest.mark.parametrize('tokenstream,output', [ - ( - [('A', 'hel'), ('A', 'lo')], - 'hello', - ), - ( - [('A', 'hel'), ('A', 'l'), ('A', 'o')], - 'hello', - ), - ( - [('A', 'hel'), ('A', 'l'), ('A', 'o')], - 'hello', - ), - ( - [('A', 'hel'), ('B', 'lo')], - 'hello', - ), - ( - [('A', 'hel'), ('B', 'lo')], - 'hello', - ), - ]) + @pytest.mark.parametrize( + "tokenstream,output", + [ + ( + [("A", "hel"), ("A", "lo")], + 'hello', + ), + ( + [("A", "hel"), ("A", "l"), ("A", "o")], + 'hello', + ), + ( + [("A", "hel"), ("A", "l"), ("A", "o")], + 'hello', + ), + ( + [("A", "hel"), ("B", "lo")], + 'hello', + ), + ( + [("A", "hel"), ("B", "lo")], + 'hello', + ), + ], + ) def test_render_tokenstream_without_ops(self, tokenstream, output): html = render_tokenstream(tokenstream) assert html == output diff --git a/rhodecode/tests/lib/test_colored_formatter.py b/rhodecode/tests/lib/test_colored_formatter.py index c8040b27..ccd9d88a 100644 --- a/rhodecode/tests/lib/test_colored_formatter.py +++ b/rhodecode/tests/lib/test_colored_formatter.py @@ -21,10 +21,13 @@ import pytest from rhodecode.lib import colored_formatter, logging_formatter -@pytest.mark.parametrize("OldFormatter, NewFormatter", [ - (colored_formatter.ColorFormatter, logging_formatter.ColorFormatter), - (colored_formatter.ColorFormatterSql, logging_formatter.ColorFormatterSql), -]) +@pytest.mark.parametrize( + "OldFormatter, NewFormatter", + [ + (colored_formatter.ColorFormatter, logging_formatter.ColorFormatter), + (colored_formatter.ColorFormatterSql, logging_formatter.ColorFormatterSql), + ], +) def test_old_formatter_names_are_still_supported(OldFormatter, NewFormatter): assert issubclass(OldFormatter, NewFormatter) pytest.deprecated_call(OldFormatter) diff --git a/rhodecode/tests/lib/test_datelib.py b/rhodecode/tests/lib/test_datelib.py index 753dd09a..76e9e3b1 100644 --- a/rhodecode/tests/lib/test_datelib.py +++ b/rhodecode/tests/lib/test_datelib.py @@ -25,7 +25,6 @@ from rhodecode.lib.datelib import date_to_timestamp_plus_offset class TestDateTotimestampPlusOffset: - def test_raises_assertion_error_if_value_is_aware(self): value = datetime.datetime(2014, 11, 26, 10, 11, tzinfo=tzutc()) with pytest.raises(AssertionError): diff --git a/rhodecode/tests/lib/test_db_manage.py b/rhodecode/tests/lib/test_db_manage.py index e49ea99d..47438531 100644 --- a/rhodecode/tests/lib/test_db_manage.py +++ b/rhodecode/tests/lib/test_db_manage.py @@ -25,9 +25,7 @@ from rhodecode.model import db @pytest.fixture() def db_manage(baseapp): - db_manage = DbManage( - log_sql=True, dbconf='fake', root='fake', tests=False, - cli_args={}, SESSION=db.Session()) + db_manage = DbManage(log_sql=True, dbconf="fake", root="fake", tests=False, cli_args={}, SESSION=db.Session()) return db_manage @@ -43,38 +41,36 @@ def session_rollback(baseapp, request): This is still a workaround until we find a way to isolate the tests better from each other. """ + @request.addfinalizer def cleanup(): db.Session().rollback() def test_create_admin_and_prompt_uses_getpass(db_manage): - db_manage.cli_args = { - 'username': 'test', - 'email': 'test@example.com'} - with mock.patch('getpass.getpass', return_value='password') as getpass: + db_manage.cli_args = {"username": "test", "email": "test@example.com"} + with mock.patch("getpass.getpass", return_value="password") as getpass: db_manage.create_admin_and_prompt() assert getpass.called def test_create_admin_and_prompt_sets_the_api_key(db_manage): db_manage.cli_args = { - 'username': 'test', - 'password': 'testpassword', - 'email': 'test@example.com', - 'api_key': 'testkey'} - with mock.patch.object(db_manage, 'create_user') as create_user: + "username": "test", + "password": "testpassword", + "email": "test@example.com", + "api_key": "testkey", + } + with mock.patch.object(db_manage, "create_user") as create_user: db_manage.create_admin_and_prompt() - assert create_user.call_args[1]['api_key'] == 'testkey' + assert create_user.call_args[1]["api_key"] == "testkey" -@pytest.mark.parametrize('add_keys', [True, False]) +@pytest.mark.parametrize("add_keys", [True, False]) def test_create_user_sets_the_api_key(db_manage, add_keys): - username = 'test_add_keys_{}'.format(add_keys) - db_manage.create_user( - username, 'testpassword', 'test@example.com', - api_key=add_keys) + username = "test_add_keys_{}".format(add_keys) + db_manage.create_user(username, "testpassword", "test@example.com", api_key=add_keys) user = db.User.get_by_username(username) if add_keys: @@ -85,6 +81,6 @@ def test_create_user_sets_the_api_key(db_manage, add_keys): def test_create_user_without_api_key(db_manage): - db_manage.create_user('test', 'testpassword', 'test@example.com') - user = db.User.get_by_username('test') + db_manage.create_user("test", "testpassword", "test@example.com") + user = db.User.get_by_username("test") assert user.api_key is None diff --git a/rhodecode/tests/lib/test_diffs.py b/rhodecode/tests/lib/test_diffs.py index 99587119..e47ce5f1 100644 --- a/rhodecode/tests/lib/test_diffs.py +++ b/rhodecode/tests/lib/test_diffs.py @@ -24,8 +24,14 @@ import pytest from rhodecode.lib.codeblocks import DiffSet from rhodecode.lib.diffs import ( DiffProcessor, - NEW_FILENODE, DEL_FILENODE, MOD_FILENODE, RENAMED_FILENODE, - CHMOD_FILENODE, BIN_FILENODE, COPIED_FILENODE) + NEW_FILENODE, + DEL_FILENODE, + MOD_FILENODE, + RENAMED_FILENODE, + CHMOD_FILENODE, + BIN_FILENODE, + COPIED_FILENODE, +) from rhodecode.lib.utils2 import AttributeDict from rhodecode.lib.vcs.backends.git import GitCommit @@ -39,32 +45,30 @@ fixture = Fixture() class TestMixedFilenameEncodings(object): - @pytest.fixture(scope="class") def raw_diff(self): - return fixture.load_resource( - 'hg_diff_mixed_filename_encodings.diff') + return fixture.load_resource("hg_diff_mixed_filename_encodings.diff") @pytest.fixture() def processor(self, raw_diff): diff = MercurialDiff(raw_diff) - processor = DiffProcessor(diff, diff_format='newdiff') + processor = DiffProcessor(diff, diff_format="newdiff") return processor def test_filenames_are_decoded_to_unicode(self, processor): diff_data = processor.prepare() - filenames = [item['filename'] for item in diff_data] - assert filenames == [ - u'späcial-utf8.txt', u'sp�cial-cp1252.txt', u'sp�cial-latin1.txt'] + filenames = [item["filename"] for item in diff_data] + assert filenames == ["späcial-utf8.txt", "sp�cial-cp1252.txt", "sp�cial-latin1.txt"] def test_raw_diff_is_decoded_to_unicode(self, processor): diff_data = processor.prepare() - raw_diffs = [item['raw_diff'] for item in diff_data] - new_file_message = u'\nnew file mode 100644\n' + raw_diffs = [item["raw_diff"] for item in diff_data] + new_file_message = "\nnew file mode 100644\n" expected_raw_diffs = [ - u' a/späcial-utf8.txt b/späcial-utf8.txt' + new_file_message, - u' a/sp�cial-cp1252.txt b/sp�cial-cp1252.txt' + new_file_message, - u' a/sp�cial-latin1.txt b/sp�cial-latin1.txt' + new_file_message] + " a/späcial-utf8.txt b/späcial-utf8.txt" + new_file_message, + " a/sp�cial-cp1252.txt b/sp�cial-cp1252.txt" + new_file_message, + " a/sp�cial-latin1.txt b/sp�cial-latin1.txt" + new_file_message, + ] assert raw_diffs == expected_raw_diffs def test_as_raw_preserves_the_encoding(self, processor, raw_diff): @@ -73,753 +77,1108 @@ class TestMixedFilenameEncodings(object): # TODO: mikhail: format the following data structure properly DIFF_FIXTURES = [ - ('hg', - 'hg_diff_add_single_binary_file.diff', - [('US Warszawa.jpg', 'A', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '100755', - 'ops': {NEW_FILENODE: 'new file 100755', - BIN_FILENODE: 'binary diff hidden'}}), - ]), - ('hg', - 'hg_diff_mod_single_binary_file.diff', - [('US Warszawa.jpg', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file', - BIN_FILENODE: 'binary diff hidden'}}), - ]), - ('hg', - 'hg_diff_mod_single_file_and_rename_and_chmod.diff', - [('README', 'M', - {'added': 3, - 'deleted': 0, - 'binary': False, - 'old_mode': '100755', - 'new_mode': '100644', - 'renamed': ('README.rst', 'README'), - 'ops': {MOD_FILENODE: 'modified file', - RENAMED_FILENODE: 'file renamed from README.rst to README', - CHMOD_FILENODE: 'modified file chmod 100755 => 100644'}}), - ]), - ('hg', - 'hg_diff_no_newline.diff', - [('server.properties', 'M', - {'added': 2, - 'deleted': 1, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'}}), - ]), - ('hg', - 'hg_diff_mod_file_and_rename.diff', - [('README.rst', 'M', - {'added': 3, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'renamed': ('README', 'README.rst'), - 'ops': {MOD_FILENODE: 'modified file', - RENAMED_FILENODE: 'file renamed from README to README.rst'}}), - ]), - ('hg', - 'hg_diff_del_single_binary_file.diff', - [('US Warszawa.jpg', 'D', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'ops': {DEL_FILENODE: 'deleted file', - BIN_FILENODE: 'binary diff hidden'}}), - ]), - ('hg', - 'hg_diff_chmod_and_mod_single_binary_file.diff', - [('gravatar.png', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '100644', - 'new_mode': '100755', - 'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755', - BIN_FILENODE: 'binary diff hidden'}}), - ]), - ('hg', - 'hg_diff_chmod.diff', - [('file', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '100755', - 'new_mode': '100644', - 'ops': {CHMOD_FILENODE: 'modified file chmod 100755 => 100644'}}), - ]), - ('hg', - 'hg_diff_rename_file.diff', - [('file_renamed', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'renamed': ('file', 'file_renamed'), - 'ops': {RENAMED_FILENODE: 'file renamed from file to file_renamed'}}), - ]), - ('hg', - 'hg_diff_rename_and_chmod_file.diff', - [('README', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '100644', - 'new_mode': '100755', - 'renamed': ('README.rst', 'README'), - 'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755', - RENAMED_FILENODE: 'file renamed from README.rst to README'}}), - ]), - ('hg', - 'hg_diff_binary_and_normal.diff', - [('img/baseline-10px.png', 'A', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'new_mode': '100644', - 'old_mode': '', - 'ops': {NEW_FILENODE: 'new file 100644', - BIN_FILENODE: 'binary diff hidden'}}), - ('js/jquery/hashgrid.js', 'A', - {'added': 340, - 'deleted': 0, - 'binary': False, - 'new_mode': '100755', - 'old_mode': '', - 'ops': {NEW_FILENODE: 'new file 100755'}}), - ('index.html', 'M', - {'added': 3, - 'deleted': 2, - 'binary': False, - 'new_mode': '', - 'old_mode': '', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('less/docs.less', 'M', - {'added': 34, - 'deleted': 0, - 'binary': False, - 'new_mode': '', - 'old_mode': '', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('less/scaffolding.less', 'M', - {'added': 1, - 'deleted': 3, - 'binary': False, - 'new_mode': '', - 'old_mode': '', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('readme.markdown', 'M', - {'added': 1, - 'deleted': 10, - 'binary': False, - 'new_mode': '', - 'old_mode': '', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('img/baseline-20px.png', 'D', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'new_mode': '', - 'old_mode': '', - 'ops': {DEL_FILENODE: 'deleted file', - BIN_FILENODE: 'binary diff hidden'}}), - ('js/global.js', 'D', - {'added': 0, - 'deleted': 75, - 'binary': False, - 'new_mode': '', - 'old_mode': '', - 'ops': {DEL_FILENODE: 'deleted file'}}) - ]), - ('git', - 'git_diff_chmod.diff', - [('work-horus.xls', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '100644', - 'new_mode': '100755', - 'ops': {CHMOD_FILENODE: 'modified file chmod 100644 => 100755'}}) - ]), - ('git', - 'git_diff_js_chars.diff', - [('\\">/\\">.txt', 'M', - {'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}) - ]), - ('git', - 'git_diff_rename_file.diff', - [('file.xls', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'renamed': ('work-horus.xls', 'file.xls'), - 'ops': { - RENAMED_FILENODE: 'file renamed from work-horus.xls to file.xls'}}) - ]), - ('git', - 'git_diff_mod_single_binary_file.diff', - [('US Warszawa.jpg', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file', - BIN_FILENODE: 'binary diff hidden'}}) - ]), - ('git', - 'git_diff_binary_and_normal.diff', - [('img/baseline-10px.png', 'A', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', - BIN_FILENODE: 'binary diff hidden'}}), - ('js/jquery/hashgrid.js', 'A', - {'added': 340, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100755', - 'ops': {NEW_FILENODE: 'new file 100755'}}), - ('index.html', 'M', - {'added': 3, - 'deleted': 2, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('less/docs.less', 'M', - {'added': 34, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('less/scaffolding.less', 'M', - {'added': 1, - 'deleted': 3, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('readme.markdown', 'M', - {'added': 1, - 'deleted': 10, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('img/baseline-20px.png', 'D', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'ops': {DEL_FILENODE: 'deleted file', - BIN_FILENODE: 'binary diff hidden'}}), - ('js/global.js', 'D', - {'added': 0, - 'deleted': 75, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {DEL_FILENODE: 'deleted file'}}), - ]), - ('hg', - 'diff_with_diff_data.diff', - [('vcs/backends/base.py', 'M', - {'added': 18, - 'deleted': 2, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('vcs/backends/git/repository.py', 'M', - {'added': 46, - 'deleted': 15, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('vcs/backends/hg.py', 'M', - {'added': 22, - 'deleted': 3, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('vcs/tests/test_git.py', 'M', - {'added': 5, - 'deleted': 5, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ('vcs/tests/test_repository.py', 'M', - {'added': 174, - 'deleted': 2, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {MOD_FILENODE: 'modified file'}}), - ]), - ('hg', - 'hg_diff_copy_file.diff', - [('file2', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'copied': ('file1', 'file2'), - 'ops': {COPIED_FILENODE: 'file copied from file1 to file2'}}), - ]), - ('hg', - 'hg_diff_copy_and_modify_file.diff', - [('file3', 'M', - {'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'copied': ('file2', 'file3'), - 'ops': {COPIED_FILENODE: 'file copied from file2 to file3', - MOD_FILENODE: 'modified file'}}), - ]), - ('hg', - 'hg_diff_copy_and_chmod_file.diff', - [('file4', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '100644', - 'new_mode': '100755', - 'copied': ('file3', 'file4'), - 'ops': {COPIED_FILENODE: 'file copied from file3 to file4', - CHMOD_FILENODE: 'modified file chmod 100644 => 100755'}}), - ]), - ('hg', - 'hg_diff_copy_chmod_and_edit_file.diff', - [('file5', 'M', - {'added': 2, - 'deleted': 1, - 'binary': False, - 'old_mode': '100755', - 'new_mode': '100644', - 'copied': ('file4', 'file5'), - 'ops': {COPIED_FILENODE: 'file copied from file4 to file5', - CHMOD_FILENODE: 'modified file chmod 100755 => 100644', - MOD_FILENODE: 'modified file'}})]), - + ( + "hg", + "hg_diff_add_single_binary_file.diff", + [ + ( + "US Warszawa.jpg", + "A", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "100755", + "ops": {NEW_FILENODE: "new file 100755", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_mod_single_binary_file.diff", + [ + ( + "US Warszawa.jpg", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_mod_single_file_and_rename_and_chmod.diff", + [ + ( + "README", + "M", + { + "added": 3, + "deleted": 0, + "binary": False, + "old_mode": "100755", + "new_mode": "100644", + "renamed": ("README.rst", "README"), + "ops": { + MOD_FILENODE: "modified file", + RENAMED_FILENODE: "file renamed from README.rst to README", + CHMOD_FILENODE: "modified file chmod 100755 => 100644", + }, + }, + ), + ], + ), + ( + "hg", + "hg_diff_no_newline.diff", + [ + ( + "server.properties", + "M", + { + "added": 2, + "deleted": 1, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_mod_file_and_rename.diff", + [ + ( + "README.rst", + "M", + { + "added": 3, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "", + "renamed": ("README", "README.rst"), + "ops": {MOD_FILENODE: "modified file", RENAMED_FILENODE: "file renamed from README to README.rst"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_del_single_binary_file.diff", + [ + ( + "US Warszawa.jpg", + "D", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "ops": {DEL_FILENODE: "deleted file", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_chmod_and_mod_single_binary_file.diff", + [ + ( + "gravatar.png", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "100644", + "new_mode": "100755", + "ops": {CHMOD_FILENODE: "modified file chmod 100644 => 100755", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_chmod.diff", + [ + ( + "file", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "100755", + "new_mode": "100644", + "ops": {CHMOD_FILENODE: "modified file chmod 100755 => 100644"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_rename_file.diff", + [ + ( + "file_renamed", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "renamed": ("file", "file_renamed"), + "ops": {RENAMED_FILENODE: "file renamed from file to file_renamed"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_rename_and_chmod_file.diff", + [ + ( + "README", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "100644", + "new_mode": "100755", + "renamed": ("README.rst", "README"), + "ops": { + CHMOD_FILENODE: "modified file chmod 100644 => 100755", + RENAMED_FILENODE: "file renamed from README.rst to README", + }, + }, + ), + ], + ), + ( + "hg", + "hg_diff_binary_and_normal.diff", + [ + ( + "img/baseline-10px.png", + "A", + { + "added": 0, + "deleted": 0, + "binary": True, + "new_mode": "100644", + "old_mode": "", + "ops": {NEW_FILENODE: "new file 100644", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ( + "js/jquery/hashgrid.js", + "A", + { + "added": 340, + "deleted": 0, + "binary": False, + "new_mode": "100755", + "old_mode": "", + "ops": {NEW_FILENODE: "new file 100755"}, + }, + ), + ( + "index.html", + "M", + { + "added": 3, + "deleted": 2, + "binary": False, + "new_mode": "", + "old_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "less/docs.less", + "M", + { + "added": 34, + "deleted": 0, + "binary": False, + "new_mode": "", + "old_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "less/scaffolding.less", + "M", + { + "added": 1, + "deleted": 3, + "binary": False, + "new_mode": "", + "old_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "readme.markdown", + "M", + { + "added": 1, + "deleted": 10, + "binary": False, + "new_mode": "", + "old_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "img/baseline-20px.png", + "D", + { + "added": 0, + "deleted": 0, + "binary": True, + "new_mode": "", + "old_mode": "", + "ops": {DEL_FILENODE: "deleted file", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ( + "js/global.js", + "D", + { + "added": 0, + "deleted": 75, + "binary": False, + "new_mode": "", + "old_mode": "", + "ops": {DEL_FILENODE: "deleted file"}, + }, + ), + ], + ), + ( + "git", + "git_diff_chmod.diff", + [ + ( + "work-horus.xls", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "100644", + "new_mode": "100755", + "ops": {CHMOD_FILENODE: "modified file chmod 100644 => 100755"}, + }, + ) + ], + ), + ( + "git", + "git_diff_js_chars.diff", + [ + ( + '\\">/\\">.txt', + "M", + { + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ) + ], + ), + ( + "git", + "git_diff_rename_file.diff", + [ + ( + "file.xls", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "renamed": ("work-horus.xls", "file.xls"), + "ops": {RENAMED_FILENODE: "file renamed from work-horus.xls to file.xls"}, + }, + ) + ], + ), + ( + "git", + "git_diff_mod_single_binary_file.diff", + [ + ( + "US Warszawa.jpg", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file", BIN_FILENODE: "binary diff hidden"}, + }, + ) + ], + ), + ( + "git", + "git_diff_binary_and_normal.diff", + [ + ( + "img/baseline-10px.png", + "A", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "100644", + "ops": {NEW_FILENODE: "new file 100644", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ( + "js/jquery/hashgrid.js", + "A", + { + "added": 340, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100755", + "ops": {NEW_FILENODE: "new file 100755"}, + }, + ), + ( + "index.html", + "M", + { + "added": 3, + "deleted": 2, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "less/docs.less", + "M", + { + "added": 34, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "less/scaffolding.less", + "M", + { + "added": 1, + "deleted": 3, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "readme.markdown", + "M", + { + "added": 1, + "deleted": 10, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "img/baseline-20px.png", + "D", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "ops": {DEL_FILENODE: "deleted file", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ( + "js/global.js", + "D", + { + "added": 0, + "deleted": 75, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {DEL_FILENODE: "deleted file"}, + }, + ), + ], + ), + ( + "hg", + "diff_with_diff_data.diff", + [ + ( + "vcs/backends/base.py", + "M", + { + "added": 18, + "deleted": 2, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "vcs/backends/git/repository.py", + "M", + { + "added": 46, + "deleted": 15, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "vcs/backends/hg.py", + "M", + { + "added": 22, + "deleted": 3, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "vcs/tests/test_git.py", + "M", + { + "added": 5, + "deleted": 5, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "vcs/tests/test_repository.py", + "M", + { + "added": 174, + "deleted": 2, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_copy_file.diff", + [ + ( + "file2", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "copied": ("file1", "file2"), + "ops": {COPIED_FILENODE: "file copied from file1 to file2"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_copy_and_modify_file.diff", + [ + ( + "file3", + "M", + { + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "", + "copied": ("file2", "file3"), + "ops": {COPIED_FILENODE: "file copied from file2 to file3", MOD_FILENODE: "modified file"}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_copy_and_chmod_file.diff", + [ + ( + "file4", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "100644", + "new_mode": "100755", + "copied": ("file3", "file4"), + "ops": { + COPIED_FILENODE: "file copied from file3 to file4", + CHMOD_FILENODE: "modified file chmod 100644 => 100755", + }, + }, + ), + ], + ), + ( + "hg", + "hg_diff_copy_chmod_and_edit_file.diff", + [ + ( + "file5", + "M", + { + "added": 2, + "deleted": 1, + "binary": False, + "old_mode": "100755", + "new_mode": "100644", + "copied": ("file4", "file5"), + "ops": { + COPIED_FILENODE: "file copied from file4 to file5", + CHMOD_FILENODE: "modified file chmod 100755 => 100644", + MOD_FILENODE: "modified file", + }, + }, + ) + ], + ), # Diffs to validate rename and copy file with space in its name - ('git', - 'git_diff_rename_file_with_spaces.diff', - [('file_with_ two spaces.txt', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'renamed': ('file_with_ spaces.txt', 'file_with_ two spaces.txt'), - 'ops': { - RENAMED_FILENODE: ( - 'file renamed from file_with_ spaces.txt to file_with_ ' - ' two spaces.txt')} - }), ]), - ('hg', - 'hg_diff_rename_file_with_spaces.diff', - [('file_changed _.txt', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'renamed': ('file_ with update.txt', 'file_changed _.txt'), - 'ops': { - RENAMED_FILENODE: ( - 'file renamed from file_ with update.txt to file_changed _.txt')} - }), ]), - ('hg', - 'hg_diff_copy_file_with_spaces.diff', - [('file_copied_ with spaces.txt', 'M', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '', - 'copied': ('file_changed_without_spaces.txt', 'file_copied_ with spaces.txt'), - 'ops': { - COPIED_FILENODE: ( - 'file copied from file_changed_without_spaces.txt to' - ' file_copied_ with spaces.txt')} - }), - ]), - + ( + "git", + "git_diff_rename_file_with_spaces.diff", + [ + ( + "file_with_ two spaces.txt", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "renamed": ("file_with_ spaces.txt", "file_with_ two spaces.txt"), + "ops": { + RENAMED_FILENODE: ("file renamed from file_with_ spaces.txt to file_with_ two spaces.txt") + }, + }, + ), + ], + ), + ( + "hg", + "hg_diff_rename_file_with_spaces.diff", + [ + ( + "file_changed _.txt", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "renamed": ("file_ with update.txt", "file_changed _.txt"), + "ops": {RENAMED_FILENODE: ("file renamed from file_ with update.txt to file_changed _.txt")}, + }, + ), + ], + ), + ( + "hg", + "hg_diff_copy_file_with_spaces.diff", + [ + ( + "file_copied_ with spaces.txt", + "M", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "", + "copied": ("file_changed_without_spaces.txt", "file_copied_ with spaces.txt"), + "ops": { + COPIED_FILENODE: ( + "file copied from file_changed_without_spaces.txt to file_copied_ with spaces.txt" + ) + }, + }, + ), + ], + ), # special signs from git - ('git', - 'git_diff_binary_special_files.diff', - [('css/_Icon\\r', 'A', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', - BIN_FILENODE: 'binary diff hidden'} - }), - ]), - ('git', - 'git_diff_binary_special_files_2.diff', - [('css/Icon\\r', 'A', - {'added': 0, - 'deleted': 0, - 'binary': True, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } - }), - ]), - - ('svn', - 'svn_diff_binary_add_file.diff', - [('intl.dll', 'A', - {'added': 0, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '10644', - 'ops': {NEW_FILENODE: 'new file 10644', - #TODO(Marcink): depends on binary detection on svn patches - # BIN_FILENODE: 'binary diff hidden' - } - }), - ]), - - ('svn', - 'svn_diff_multiple_changes.diff', - [('trunk/doc/images/SettingsOverlay.png', 'M', - {'added': 0, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file', - #TODO(Marcink): depends on binary detection on svn patches - # BIN_FILENODE: 'binary diff hidden' - } - }), - ('trunk/doc/source/de/tsvn_ch04.xml', 'M', - {'added': 89, - 'deleted': 34, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ('trunk/doc/source/en/tsvn_ch04.xml', 'M', - {'added': 66, - 'deleted': 21, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ('trunk/src/Changelog.txt', 'M', - {'added': 2, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ('trunk/src/Resources/TortoiseProcENG.rc', 'M', - {'added': 19, - 'deleted': 13, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ('trunk/src/TortoiseProc/SetOverlayPage.cpp', 'M', - {'added': 16, - 'deleted': 1, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ('trunk/src/TortoiseProc/SetOverlayPage.h', 'M', - {'added': 3, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ('trunk/src/TortoiseProc/resource.h', 'M', - {'added': 2, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ('trunk/src/TortoiseShell/ShellCache.h', 'M', - {'added': 50, - 'deleted': 1, - 'binary': False, - 'old_mode': '', - 'new_mode': '', - 'ops': {MOD_FILENODE: 'modified file'} - }), - ]), - + ( + "git", + "git_diff_binary_special_files.diff", + [ + ( + "css/_Icon\\r", + "A", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "100644", + "ops": {NEW_FILENODE: "new file 100644", BIN_FILENODE: "binary diff hidden"}, + }, + ), + ], + ), + ( + "git", + "git_diff_binary_special_files_2.diff", + [ + ( + "css/Icon\\r", + "A", + { + "added": 0, + "deleted": 0, + "binary": True, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, + }, + ), + ], + ), + ( + "svn", + "svn_diff_binary_add_file.diff", + [ + ( + "intl.dll", + "A", + { + "added": 0, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "10644", + "ops": { + NEW_FILENODE: "new file 10644", + # TODO(Marcink): depends on binary detection on svn patches + # BIN_FILENODE: 'binary diff hidden' + }, + }, + ), + ], + ), + ( + "svn", + "svn_diff_multiple_changes.diff", + [ + ( + "trunk/doc/images/SettingsOverlay.png", + "M", + { + "added": 0, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": { + MOD_FILENODE: "modified file", + # TODO(Marcink): depends on binary detection on svn patches + # BIN_FILENODE: 'binary diff hidden' + }, + }, + ), + ( + "trunk/doc/source/de/tsvn_ch04.xml", + "M", + { + "added": 89, + "deleted": 34, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "trunk/doc/source/en/tsvn_ch04.xml", + "M", + { + "added": 66, + "deleted": 21, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "trunk/src/Changelog.txt", + "M", + { + "added": 2, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "trunk/src/Resources/TortoiseProcENG.rc", + "M", + { + "added": 19, + "deleted": 13, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "trunk/src/TortoiseProc/SetOverlayPage.cpp", + "M", + { + "added": 16, + "deleted": 1, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "trunk/src/TortoiseProc/SetOverlayPage.h", + "M", + { + "added": 3, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "trunk/src/TortoiseProc/resource.h", + "M", + { + "added": 2, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ( + "trunk/src/TortoiseShell/ShellCache.h", + "M", + { + "added": 50, + "deleted": 1, + "binary": False, + "old_mode": "", + "new_mode": "", + "ops": {MOD_FILENODE: "modified file"}, + }, + ), + ], + ), ] DIFF_FIXTURES_WITH_CONTENT = [ ( - 'hg', 'hg_diff_single_file_change_newline.diff', + "hg", + "hg_diff_single_file_change_newline.diff", [ ( - 'file_b', # filename - 'A', # change + "file_b", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1 @@\n+test_content b\n' # diff + "@@ -0,0 +1 @@\n+test_content b\n", # diff ), ], ), ( - 'hg', 'hg_diff_double_file_change_newline.diff', + "hg", + "hg_diff_double_file_change_newline.diff", [ ( - 'file_b', # filename - 'A', # change + "file_b", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1 @@\n+test_content b\n' # diff + "@@ -0,0 +1 @@\n+test_content b\n", # diff ), ( - 'file_c', # filename - 'A', # change + "file_c", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1 @@\n+test_content c\n' # diff + "@@ -0,0 +1 @@\n+test_content c\n", # diff ), ], ), ( - 'hg', 'hg_diff_double_file_change_double_newline.diff', + "hg", + "hg_diff_double_file_change_double_newline.diff", [ ( - 'file_b', # filename - 'A', # change + "file_b", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1 @@\n+test_content b\n\n' # diff + "@@ -0,0 +1 @@\n+test_content b\n\n", # diff ), ( - 'file_c', # filename - 'A', # change + "file_c", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1 @@\n+test_content c\n' # diff + "@@ -0,0 +1 @@\n+test_content c\n", # diff ), ], ), ( - 'hg', 'hg_diff_four_file_change_newline.diff', + "hg", + "hg_diff_four_file_change_newline.diff", [ ( - 'file', # filename - 'A', # change + "file", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1,1 @@\n+file\n' # diff + "@@ -0,0 +1,1 @@\n+file\n", # diff ), ( - 'file2', # filename - 'A', # change + "file2", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1,1 @@\n+another line\n' # diff + "@@ -0,0 +1,1 @@\n+another line\n", # diff ), ( - 'file3', # filename - 'A', # change + "file3", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1,1 @@\n+newline\n' # diff + "@@ -0,0 +1,1 @@\n+newline\n", # diff ), ( - 'file4', # filename - 'A', # change + "file4", # filename + "A", # change { # stats - 'added': 1, - 'deleted': 0, - 'binary': False, - 'old_mode': '', - 'new_mode': '100644', - 'ops': {NEW_FILENODE: 'new file 100644', } + "added": 1, + "deleted": 0, + "binary": False, + "old_mode": "", + "new_mode": "100644", + "ops": { + NEW_FILENODE: "new file 100644", + }, }, - '@@ -0,0 +1,1 @@\n+fil4\n\\ No newline at end of file' # diff + "@@ -0,0 +1,1 @@\n+fil4\n\\ No newline at end of file", # diff ), ], ), - ] diff_class = { - 'git': GitDiff, - 'hg': MercurialDiff, - 'svn': SubversionDiff, + "git": GitDiff, + "hg": MercurialDiff, + "svn": SubversionDiff, } -@pytest.mark.parametrize('vcs_type, diff_file, expected_data', DIFF_FIXTURES) +@pytest.mark.parametrize("vcs_type, diff_file, expected_data", DIFF_FIXTURES) def test_diff_lib(vcs_type, diff_file, expected_data): diff_txt = fixture.load_resource(diff_file) diff = diff_class[vcs_type](diff_txt) - diff_proc = DiffProcessor(diff, diff_format='newdiff') + diff_proc = DiffProcessor(diff, diff_format="newdiff") diff_proc_d = diff_proc.prepare() - data = [(x['filename'], x['operation'], x['stats']) - for x in diff_proc_d] + data = [(x["filename"], x["operation"], x["stats"]) for x in diff_proc_d] assert expected_data == data -@pytest.mark.parametrize('vcs_type, diff_file, expected_data', DIFF_FIXTURES_WITH_CONTENT) +@pytest.mark.parametrize("vcs_type, diff_file, expected_data", DIFF_FIXTURES_WITH_CONTENT) def test_diff_lib_newlines(vcs_type, diff_file, expected_data): diff_txt = fixture.load_resource(diff_file) diff = diff_class[vcs_type](diff_txt) - diff_proc = DiffProcessor(diff, diff_format='newdiff') + diff_proc = DiffProcessor(diff, diff_format="newdiff") diff_proc_d = diff_proc.prepare() - data = [(x['filename'], x['operation'], x['stats'], x['raw_diff']) - for x in diff_proc_d] + data = [(x["filename"], x["operation"], x["stats"], x["raw_diff"]) for x in diff_proc_d] assert expected_data == data -@pytest.mark.parametrize('input_str', [ - b'', - b'\n', - b'\n\n', - b'First\n+second', - b'First\n+second\n', - - b'\n\n\n Multi \n\n\n', - b'\n\n\n Multi beginning', - b'Multi end \n\n\n', - b'Multi end', - b'@@ -0,0 +1 @@\n+test_content \n\n b\n' -], ids=no_newline_id_generator) +@pytest.mark.parametrize( + "input_str", + [ + b"", + b"\n", + b"\n\n", + b"First\n+second", + b"First\n+second\n", + b"\n\n\n Multi \n\n\n", + b"\n\n\n Multi beginning", + b"Multi end \n\n\n", + b"Multi end", + b"@@ -0,0 +1 @@\n+test_content \n\n b\n", + ], + ids=no_newline_id_generator, +) def test_splitlines(input_str): result = DiffProcessor.diff_splitter(input_str) assert list(result) == input_str.splitlines(True) def test_diff_over_limit(request): - diff_limit = 1024 file_limit = 1024 - raw_diff = fixture.load_resource('large_diff.diff') + raw_diff = fixture.load_resource("large_diff.diff") vcs_diff = GitDiff(raw_diff) - diff_processor = DiffProcessor(vcs_diff, diff_format='newdiff', - diff_limit=diff_limit, file_limit=file_limit, - show_full_diff=False) + diff_processor = DiffProcessor( + vcs_diff, diff_format="newdiff", diff_limit=diff_limit, file_limit=file_limit, show_full_diff=False + ) _parsed = diff_processor.prepare() - commit1 = GitCommit(repository=mock.Mock(), raw_id='abcdef12', idx=1) - commit2 = GitCommit(repository=mock.Mock(), raw_id='abcdef34', idx=2) + commit1 = GitCommit(repository=mock.Mock(), raw_id="abcdef12", idx=1) + commit2 = GitCommit(repository=mock.Mock(), raw_id="abcdef34", idx=2) diffset = DiffSet( - repo_name='repo_name', - source_node_getter=lambda *a, **kw: AttributeDict({'commit': commit1}), - target_node_getter=lambda *a, **kw: AttributeDict({'commit': commit2}) + repo_name="repo_name", + source_node_getter=lambda *a, **kw: AttributeDict({"commit": commit1}), + target_node_getter=lambda *a, **kw: AttributeDict({"commit": commit2}), ) diffset = diffset.render_patchset(_parsed, commit1, commit2) assert len(diffset.files) == 2 assert diffset.limited_diff is True - assert diffset.files[0].patch['filename'] == 'example.go' + assert diffset.files[0].patch["filename"] == "example.go" assert diffset.files[0].limited_diff is True - assert diffset.files[1].patch['filename'] == 'README.md' + assert diffset.files[1].patch["filename"] == "README.md" assert diffset.files[1].limited_diff is False diff --git a/rhodecode/tests/lib/test_diffs_context.py b/rhodecode/tests/lib/test_diffs_context.py index 48ef622a..a156ab14 100644 --- a/rhodecode/tests/lib/test_diffs_context.py +++ b/rhodecode/tests/lib/test_diffs_context.py @@ -31,36 +31,33 @@ from rhodecode.lib.vcs.backends.git.diff import GitDiff def test_context_of_new_and_old_line_number_raises(diff_processor): with pytest.raises(ValueError): - diff_processor.get_context_of_line( - path='file.txt', diff_line=diffs.DiffLineNumber(old=7, new=7)) + diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=7, new=7)) def test_context_of_an_old_line_number(diff_processor): - context = diff_processor.get_context_of_line( - path='file.txt', diff_line=diffs.DiffLineNumber(old=7, new=None)) + context = diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=7, new=None)) expected_context = [ - ('unmod', b'line04\n'), - ('unmod', b'line05\n'), - ('unmod', b'line06\n'), - ('unmod', b'line07\n'), - ('add', b'line07a Add after line07\n'), - ('unmod', b'line08\n'), - ('unmod', b'line09\n'), + ("unmod", b"line04\n"), + ("unmod", b"line05\n"), + ("unmod", b"line06\n"), + ("unmod", b"line07\n"), + ("add", b"line07a Add after line07\n"), + ("unmod", b"line08\n"), + ("unmod", b"line09\n"), ] assert context == expected_context def test_context_of_a_new_line_number(diff_processor): - context = diff_processor.get_context_of_line( - path='file.txt', diff_line=diffs.DiffLineNumber(old=None, new=8)) + context = diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=None, new=8)) expected_context = [ - ('unmod', b'line05\n'), - ('unmod', b'line06\n'), - ('unmod', b'line07\n'), - ('add', b'line07a Add after line07\n'), - ('unmod', b'line08\n'), - ('unmod', b'line09\n'), - ('unmod', b'line10\n'), + ("unmod", b"line05\n"), + ("unmod", b"line06\n"), + ("unmod", b"line07\n"), + ("add", b"line07a Add after line07\n"), + ("unmod", b"line08\n"), + ("unmod", b"line09\n"), + ("unmod", b"line10\n"), ] assert context == expected_context @@ -68,14 +65,13 @@ def test_context_of_a_new_line_number(diff_processor): def test_context_of_an_invisible_line_beginning_of_hunk(diff_processor): # Note: The caller has to pass in a diff which is suitable to satisfy # its requirements. This test just ensures that we see a sane behavior. - context = diff_processor.get_context_of_line( - path='file.txt', diff_line=diffs.DiffLineNumber(old=None, new=3)) + context = diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=None, new=3)) expected_context = [ - ('unmod', b'line02\n'), - ('unmod', b'line03\n'), - ('unmod', b'line04\n'), - ('unmod', b'line05\n'), - ('unmod', b'line06\n'), + ("unmod", b"line02\n"), + ("unmod", b"line03\n"), + ("unmod", b"line04\n"), + ("unmod", b"line05\n"), + ("unmod", b"line06\n"), ] assert context == expected_context @@ -83,157 +79,149 @@ def test_context_of_an_invisible_line_beginning_of_hunk(diff_processor): def test_context_of_an_invisible_line_end_of_hunk(diff_processor): # Note: The caller has to pass in a diff which is suitable to satisfy # its requirements. This test just ensures that we see a sane behavior. - context = diff_processor.get_context_of_line( - path='file.txt', diff_line=diffs.DiffLineNumber(old=12, new=None)) + context = diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=12, new=None)) expected_context = [ - ('unmod', b'line09\n'), - ('unmod', b'line10\n'), - ('unmod', b'line11\n'), - ('unmod', b'line12\n'), - ('unmod', b'line13\n'), + ("unmod", b"line09\n"), + ("unmod", b"line10\n"), + ("unmod", b"line11\n"), + ("unmod", b"line12\n"), + ("unmod", b"line13\n"), ] assert context == expected_context -@pytest.mark.parametrize('diff_fixture', ['change-in-beginning.diff']) +@pytest.mark.parametrize("diff_fixture", ["change-in-beginning.diff"]) def test_context_of_an_incomplete_hunk_in_the_beginning(diff_processor): - context = diff_processor.get_context_of_line( - path='file.txt', diff_line=diffs.DiffLineNumber(old=None, new=2)) + context = diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=None, new=2)) expected_context = [ - ('unmod', b'line01\n'), - ('add', b'line01a Add line after line01\n'), - ('unmod', b'line02\n'), - ('unmod', b'line03\n'), - ('unmod', b'line04\n'), + ("unmod", b"line01\n"), + ("add", b"line01a Add line after line01\n"), + ("unmod", b"line02\n"), + ("unmod", b"line03\n"), + ("unmod", b"line04\n"), ] assert context == expected_context -@pytest.mark.parametrize('diff_fixture', ['change-in-end.diff']) +@pytest.mark.parametrize("diff_fixture", ["change-in-end.diff"]) def test_context_of_an_incomplete_hunk_in_the_end(diff_processor): - context = diff_processor.get_context_of_line( - path='file.txt', diff_line=diffs.DiffLineNumber(old=None, new=80)) + context = diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=None, new=80)) expected_context = [ - ('unmod', b'line36\n'), - ('unmod', b'line37\n'), - ('unmod', b'line38\n'), - ('add', b'line38a Add line after line38\n'), - ('unmod', b'line39\n'), + ("unmod", b"line36\n"), + ("unmod", b"line37\n"), + ("unmod", b"line38\n"), + ("add", b"line38a Add line after line38\n"), + ("unmod", b"line39\n"), ] assert context == expected_context -@pytest.mark.parametrize('diff_fixture', [ - 'single-line.diff', - 'single-line-two-files.diff', -]) +@pytest.mark.parametrize( + "diff_fixture", + [ + "single-line.diff", + "single-line-two-files.diff", + ], +) def test_appends_newline_for_each_context_line(diff_processor): - context = diff_processor.get_context_of_line( - path='file_b', diff_line=diffs.DiffLineNumber(old=None, new=1)) - assert context == [('add', b'test_content\n')] + context = diff_processor.get_context_of_line(path="file_b", diff_line=diffs.DiffLineNumber(old=None, new=1)) + assert context == [("add", b"test_content\n")] def test_context_of_a_missing_line_raises(diff_processor): missing_line = 20 with pytest.raises(diffs.LineNotInDiffException): - diff_processor.get_context_of_line( - path='file.txt', - diff_line=diffs.DiffLineNumber(old=None, new=missing_line)) + diff_processor.get_context_of_line(path="file.txt", diff_line=diffs.DiffLineNumber(old=None, new=missing_line)) def test_context_of_a_missing_file_raises(diff_processor): with pytest.raises(diffs.FileNotInDiffException): diff_processor.get_context_of_line( - path='not_existing_file.txt', - diff_line=diffs.DiffLineNumber(old=None, new=8)) + path="not_existing_file.txt", diff_line=diffs.DiffLineNumber(old=None, new=8) + ) def test_find_context_with_full_context(diff_processor): context_of_line_7 = [ - ('unmod', b'line05\n'), - ('unmod', b'line06\n'), - ('unmod', b'line07\n'), - ('add', b'line07a Add after line07\n'), - ('unmod', b'line08\n'), - ('unmod', b'line09\n'), - ('unmod', b'line10\n'), + ("unmod", b"line05\n"), + ("unmod", b"line06\n"), + ("unmod", b"line07\n"), + ("add", b"line07a Add after line07\n"), + ("unmod", b"line08\n"), + ("unmod", b"line09\n"), + ("unmod", b"line10\n"), ] - found_line = diff_processor.find_context( - 'file.txt', context_of_line_7, offset=3) + found_line = diff_processor.find_context("file.txt", context_of_line_7, offset=3) assert found_line == [diffs.DiffLineNumber(old=None, new=8)] -@pytest.mark.parametrize('diff_fixture', ['change-duplicated.diff']) +@pytest.mark.parametrize("diff_fixture", ["change-duplicated.diff"]) def test_find_context_multiple_times(diff_processor): context = [ - ('unmod', b'line04\n'), - ('unmod', b'line05\n'), - ('unmod', b'line06\n'), - ('add', b'line06a add line\n'), - ('unmod', b'line07\n'), - ('unmod', b'line08\n'), - ('unmod', b'line09\n'), + ("unmod", b"line04\n"), + ("unmod", b"line05\n"), + ("unmod", b"line06\n"), + ("add", b"line06a add line\n"), + ("unmod", b"line07\n"), + ("unmod", b"line08\n"), + ("unmod", b"line09\n"), ] - found_line = diff_processor.find_context('file.txt', context, offset=3) + found_line = diff_processor.find_context("file.txt", context, offset=3) assert found_line == [ diffs.DiffLineNumber(old=None, new=7), diffs.DiffLineNumber(old=None, new=49), ] -@pytest.mark.parametrize('offset', [20, -20, -1, 7]) +@pytest.mark.parametrize("offset", [20, -20, -1, 7]) def test_find_context_offset_param_raises(diff_processor, offset): context_of_line_7 = [ - ('unmod', b'line04\n'), - ('unmod', b'line05\n'), - ('unmod', b'line06\n'), - ('unmod', b'line07\n'), - ('add', b'line07a Add after line07\n'), - ('unmod', b'line08\n'), - ('unmod', b'line09\n'), + ("unmod", b"line04\n"), + ("unmod", b"line05\n"), + ("unmod", b"line06\n"), + ("unmod", b"line07\n"), + ("add", b"line07a Add after line07\n"), + ("unmod", b"line08\n"), + ("unmod", b"line09\n"), ] with pytest.raises(ValueError): - diff_processor.find_context( - 'file.txt', context_of_line_7, offset=offset) + diff_processor.find_context("file.txt", context_of_line_7, offset=offset) def test_find_context_beginning_of_chunk(diff_processor): context_of_first_line = [ - ('unmod', b'line02\n'), - ('unmod', b'line03\n'), - ('unmod', b'line04\n'), - ('unmod', b'line05\n'), + ("unmod", b"line02\n"), + ("unmod", b"line03\n"), + ("unmod", b"line04\n"), + ("unmod", b"line05\n"), ] - found_line = diff_processor.find_context( - 'file.txt', context_of_first_line, offset=0) + found_line = diff_processor.find_context("file.txt", context_of_first_line, offset=0) assert found_line == [diffs.DiffLineNumber(old=2, new=2)] -@pytest.mark.parametrize('diff_fixture', ['change-in-beginning.diff']) +@pytest.mark.parametrize("diff_fixture", ["change-in-beginning.diff"]) def test_find_context_beginning_of_file(diff_processor): context_of_first_line = [ - ('add', b'line01a Add line after line01\n'), - ('unmod', b'line02\n'), - ('unmod', b'line03\n'), - ('unmod', b'line04\n'), - ('unmod', b'line05\n'), - ('unmod', b'line06\n'), - ('unmod', b'line07\n'), + ("add", b"line01a Add line after line01\n"), + ("unmod", b"line02\n"), + ("unmod", b"line03\n"), + ("unmod", b"line04\n"), + ("unmod", b"line05\n"), + ("unmod", b"line06\n"), + ("unmod", b"line07\n"), ] - found_line = diff_processor.find_context( - 'file.txt', context_of_first_line, offset=3) + found_line = diff_processor.find_context("file.txt", context_of_first_line, offset=3) assert found_line == [diffs.DiffLineNumber(old=4, new=5)] def test_find_context_end_of_chunk(diff_processor): context_of_last_line = [ - ('unmod', b'line10\n'), - ('unmod', b'line11\n'), - ('unmod', b'line12\n'), - ('unmod', b'line13\n'), + ("unmod", b"line10\n"), + ("unmod", b"line11\n"), + ("unmod", b"line12\n"), + ("unmod", b"line13\n"), ] - found_line = diff_processor.find_context( - 'file.txt', context_of_last_line, offset=3) + found_line = diff_processor.find_context("file.txt", context_of_last_line, offset=3) assert found_line == [diffs.DiffLineNumber(old=13, new=14)] @@ -241,17 +229,18 @@ def test_find_context_end_of_chunk(diff_processor): def diff_processor(request, diff_fixture): raw_diff = diffs_store[diff_fixture] diff = GitDiff(raw_diff) - processor = diffs.DiffProcessor(diff, diff_format='newdiff') + processor = diffs.DiffProcessor(diff, diff_format="newdiff") processor.prepare() return processor @pytest.fixture() def diff_fixture(): - return 'default.diff' + return "default.diff" -diff_default: bytes = safe_bytes(textwrap.dedent(""" +diff_default: bytes = safe_bytes( + textwrap.dedent(""" diff --git a/file.txt b/file.txt index 76e4f2e..6f8738f 100644 --- a/file.txt @@ -270,10 +259,12 @@ diff_default: bytes = safe_bytes(textwrap.dedent(""" line11 line12 line13 -""")) +""") +) -diff_beginning: bytes = safe_bytes(textwrap.dedent(""" +diff_beginning: bytes = safe_bytes( + textwrap.dedent(""" diff --git a/file.txt b/file.txt index 76e4f2e..47d39f4 100644 --- a/file.txt @@ -287,10 +278,12 @@ diff_beginning: bytes = safe_bytes(textwrap.dedent(""" line05 line06 line07 -""")) +""") +) -diff_end: bytes = safe_bytes(textwrap.dedent(""" +diff_end: bytes = safe_bytes( + textwrap.dedent(""" diff --git a/file.txt b/file.txt index 76e4f2e..b1304db 100644 --- a/file.txt @@ -304,10 +297,12 @@ diff_end: bytes = safe_bytes(textwrap.dedent(""" line38 +line38a Add line after line38 line39 -""")) +""") +) -diff_duplicated_change: bytes = safe_bytes(textwrap.dedent(""" +diff_duplicated_change: bytes = safe_bytes( + textwrap.dedent(""" diff --git a/file.txt b/file.txt index 76e4f2e..55c2781 100644 --- a/file.txt @@ -340,10 +335,12 @@ diff_duplicated_change: bytes = safe_bytes(textwrap.dedent(""" line10 line11 line12 -""")) +""") +) -diff_single_line: bytes = safe_bytes(textwrap.dedent(""" +diff_single_line: bytes = safe_bytes( + textwrap.dedent(""" diff --git a/file_b b/file_b new file mode 100644 index 00000000..915e94ff @@ -351,10 +348,12 @@ diff_single_line: bytes = safe_bytes(textwrap.dedent(""" +++ b/file_b @@ -0,0 +1 @@ +test_content -""")) +""") +) -diff_single_line_two_files: bytes = safe_bytes(textwrap.dedent(""" +diff_single_line_two_files: bytes = safe_bytes( + textwrap.dedent(""" diff --git a/file_b b/file_b new file mode 100644 index 00000000..915e94ff @@ -369,14 +368,15 @@ diff_single_line_two_files: bytes = safe_bytes(textwrap.dedent(""" +++ b/file_c @@ -0,0 +1 @@ +test_content -""")) +""") +) diffs_store = { - 'default.diff': diff_default, - 'change-in-beginning.diff': diff_beginning, - 'change-in-end.diff': diff_end, - 'change-duplicated.diff': diff_duplicated_change, - 'single-line.diff': diff_single_line, - 'single-line-two-files.diff': diff_single_line_two_files, + "default.diff": diff_default, + "change-in-beginning.diff": diff_beginning, + "change-in-end.diff": diff_end, + "change-duplicated.diff": diff_duplicated_change, + "single-line.diff": diff_single_line, + "single-line-two-files.diff": diff_single_line_two_files, } diff --git a/rhodecode/tests/lib/test_encrypt.py b/rhodecode/tests/lib/test_encrypt.py index 1d39d94d..c371724f 100644 --- a/rhodecode/tests/lib/test_encrypt.py +++ b/rhodecode/tests/lib/test_encrypt.py @@ -18,28 +18,29 @@ import pytest -from rhodecode.lib.encrypt import ( - AESCipher, InvalidDecryptedValue) +from rhodecode.lib.encrypt import AESCipher, InvalidDecryptedValue from rhodecode.lib import enc_utils from rhodecode.lib.str_utils import safe_str from rhodecode.lib.exceptions import SignatureVerificationError @pytest.mark.parametrize( - "algo", ['fernet', 'aes'], + "algo", + ["fernet", "aes"], ) @pytest.mark.parametrize( "key, text", [ - (b'a', 'short'), - (b'a' * 64, 'too long(trimmed to 32)'), - (b'a' * 32, 'just enough'), - ('ąćęćę', 'non asci'), - ('$asa$asa', 'special $ used'), - ] + (b"a", "short"), + (b"a" * 64, "too long(trimmed to 32)"), + (b"a" * 32, "just enough"), + ("ąćęćę", "non asci"), + ("$asa$asa", "special $ used"), + ], ) @pytest.mark.parametrize( - "strict_mode", [True, False], + "strict_mode", + [True, False], ) def test_common_encryption_module(algo, key, text, strict_mode): encrypted = enc_utils.encrypt_value(text, algo=algo, enc_key=key) @@ -48,87 +49,89 @@ def test_common_encryption_module(algo, key, text, strict_mode): @pytest.mark.parametrize( - "algo", ['fernet', 'aes'], + "algo", + ["fernet", "aes"], ) def test_encryption_with_bad_key(algo): - key = b'secretstring' - text = b'ihatemysql' + key = b"secretstring" + text = b"ihatemysql" encrypted = enc_utils.encrypt_value(text, algo=algo, enc_key=key) - decrypted = enc_utils.decrypt_value(encrypted, algo=algo, enc_key=b'different-key', strict_mode=False) + decrypted = enc_utils.decrypt_value(encrypted, algo=algo, enc_key=b"different-key", strict_mode=False) - assert decrypted[:22] == 'https://rc.com'), - (r'https://rc.com/test', 'https://rc.com/test'), - (r'https://rc.com/!foo', 'https://rc.com/!foo'), - (r'https://rc.com/&foo', 'https://rc.com/&foo'), - (r'https://rc.com/?foo-1&bar=1', 'https://rc.com/?foo-1&bar=1'), - (r'https://rc.com?foo-1&bar=1', 'https://rc.com?foo-1&bar=1'), - (r'https://rc.com/#foo', 'https://rc.com/#foo'), - (r'https://rc.com/@foo', 'https://rc.com/@foo'), -]) +@pytest.mark.parametrize( + "url, expected_url", + [ + (r"https://rc.com", 'https://rc.com'), + (r"https://rc.com/test", 'https://rc.com/test'), + (r"https://rc.com/!foo", 'https://rc.com/!foo'), + (r"https://rc.com/&foo", 'https://rc.com/&foo'), + ( + r"https://rc.com/?foo-1&bar=1", + 'https://rc.com/?foo-1&bar=1', + ), + (r"https://rc.com?foo-1&bar=1", 'https://rc.com?foo-1&bar=1'), + (r"https://rc.com/#foo", 'https://rc.com/#foo'), + (r"https://rc.com/@foo", 'https://rc.com/@foo'), + ], +) def test_urlify_text(url, expected_url): assert helpers.urlify_text(url) == expected_url -@pytest.mark.parametrize('repo_name, commit_id, path, expected_result', [ - # Simple case 1 - ('repo', 'commit', 'a/b', - '' - ' / ' - 'a' - ' / ' - 'b'), - - # Simple case - ('rX' - ' / ' - 'pX<X' - ' / ' - 'aX<X' - ' / ' - 'bX<X'), - - # Path with only one segment - ('rX' - ' / ' - 'pX<X'), - - # Empty path - ('rX
'), - - # simple quote - ('rX"X', 'cX"X', 'pX"X/aX"X/bX"X', - '' - ' / ' - 'pX"X' - ' / ' - 'aX"X' - ' / ' - 'bX"X'), - -], ids=['simple1', 'simple2', 'one_segment', 'empty_path', 'simple_quote']) +@pytest.mark.parametrize( + "repo_name, commit_id, path, expected_result", + [ + # Simple case 1 + ( + "repo", + "commit", + "a/b", + ' / a / b', + ), + # Simple case + ( + "rX' + " / " + 'pX<X' + " / " + 'aX<X' + " / " + "bX<X", + ), + # Path with only one segment + ("rX / pX<X'), + # Empty path + ("rX
'), + # simple quote + ( + 'rX"X', + 'cX"X', + 'pX"X/aX"X/bX"X', + '' + " / " + 'pX"X' + " / " + 'aX"X' + " / " + "bX"X", + ), + ], + ids=["simple1", "simple2", "one_segment", "empty_path", "simple_quote"], +) def test_files_breadcrumbs_xss(repo_name, commit_id, path, app, expected_result): - result = helpers.files_breadcrumbs(repo_name, 'hg', commit_id, path) + result = helpers.files_breadcrumbs(repo_name, "hg", commit_id, path) # Expect it to encode all path fragments properly. This is important # because it returns an instance of `literal`. - if path != '': + if path != "": expected_result = expected_result + helpers.files_icon.format(helpers.escape(path)) assert result == expected_result def test_format_binary(): - assert helpers.format_byte_size_binary(298489462784) == '278.0 GiB' + assert helpers.format_byte_size_binary(298489462784) == "278.0 GiB" -@pytest.mark.parametrize('text_string, pattern, expected', [ - ('No issue here', r'(?:#)(?P\d+)', []), - ('Fix #42', r'(?:#)(?P\d+)', - [{'url': 'https://r.io/{repo}/i/42', 'id': '42'}]), - ('Fix #42, #53', r'(?:#)(?P\d+)', [ - {'url': 'https://r.io/{repo}/i/42', 'id': '42'}, - {'url': 'https://r.io/{repo}/i/53', 'id': '53'}]), - ('Fix #42', r'(?:#)?\d+)', []), # Broken regex -]) +@pytest.mark.parametrize( + "text_string, pattern, expected", + [ + ("No issue here", r"(?:#)(?P\d+)", []), + ("Fix #42", r"(?:#)(?P\d+)", [{"url": "https://r.io/{repo}/i/42", "id": "42"}]), + ( + "Fix #42, #53", + r"(?:#)(?P\d+)", + [{"url": "https://r.io/{repo}/i/42", "id": "42"}, {"url": "https://r.io/{repo}/i/53", "id": "53"}], + ), + ("Fix #42", r"(?:#)?\d+)", []), # Broken regex + ], +) def test_extract_issues(backend, text_string, pattern, expected): repo = backend.create_repo() config = { - '123': { - 'uid': '123', - 'pat': pattern, - 'url': r'https://r.io/${repo}/i/${issue_id}', - 'pref': '#', - 'desc': 'Test Pattern' + "123": { + "uid": "123", + "pat": pattern, + "url": r"https://r.io/${repo}/i/${issue_id}", + "pref": "#", + "desc": "Test Pattern", } } def get_settings_mock(self, cache=True): return config - with mock.patch.object(IssueTrackerSettingsModel, - 'get_settings', get_settings_mock): + with mock.patch.object(IssueTrackerSettingsModel, "get_settings", get_settings_mock): text, issues, errors = helpers.process_patterns(text_string, repo.repo_name) expected = copy.deepcopy(expected) for item in expected: - item['url'] = item['url'].format(repo=repo.repo_name) + item["url"] = item["url"].format(repo=repo.repo_name) assert issues == expected -@pytest.mark.parametrize('text_string, pattern, link_format, expected_text', [ - ('Fix #42', r'(?:#)(?P\d+)', 'html', - 'Fix #42'), - - ('Fix #42', r'(?:#)(?P\d+)', 'markdown', - 'Fix [#42](https://r.io/{repo}/i/42)'), - - ('Fix #42', r'(?:#)(?P\d+)', 'rst', - 'Fix `#42 `_'), - - ('Fix #42', r'(?:#)?\d+)', 'html', - 'Fix #42'), # Broken regex -]) +@pytest.mark.parametrize( + "text_string, pattern, link_format, expected_text", + [ + ( + "Fix #42", + r"(?:#)(?P\d+)", + "html", + 'Fix #42', + ), + ("Fix #42", r"(?:#)(?P\d+)", "markdown", "Fix [#42](https://r.io/{repo}/i/42)"), + ("Fix #42", r"(?:#)(?P\d+)", "rst", "Fix `#42 `_"), + ("Fix #42", r"(?:#)?\d+)", "html", "Fix #42"), # Broken regex + ], +) def test_process_patterns_repo(backend, text_string, pattern, expected_text, link_format): repo = backend.create_repo() def get_settings_mock(self, cache=True): return { - '123': { - 'uid': '123', - 'pat': pattern, - 'url': 'https://r.io/${repo}/i/${issue_id}', - 'pref': '#', - 'desc': 'Test Pattern' + "123": { + "uid": "123", + "pat": pattern, + "url": "https://r.io/${repo}/i/${issue_id}", + "pref": "#", + "desc": "Test Pattern", } } - with mock.patch.object(IssueTrackerSettingsModel, - 'get_settings', get_settings_mock): - processed_text, issues, error = helpers.process_patterns( - text_string, repo.repo_name, link_format) + with mock.patch.object(IssueTrackerSettingsModel, "get_settings", get_settings_mock): + processed_text, issues, error = helpers.process_patterns(text_string, repo.repo_name, link_format) assert processed_text == expected_text.format(repo=repo.repo_name) -@pytest.mark.parametrize('text_string, pattern, expected_text', [ - ('Fix #42', r'(?:#)(?P\d+)', - 'Fix #42'), - ('Fix #42', r'(?:#)?\d+)', - 'Fix #42'), # Broken regex -]) +@pytest.mark.parametrize( + "text_string, pattern, expected_text", + [ + ( + "Fix #42", + r"(?:#)(?P\d+)", + 'Fix #42', + ), + ("Fix #42", r"(?:#)?\d+)", "Fix #42"), # Broken regex + ], +) def test_process_patterns_no_repo(text_string, pattern, expected_text): - def get_settings_mock(self, cache=True): return { - '123': { - 'uid': '123', - 'pat': pattern, - 'url': 'https://r.io/i/${issue_id}', - 'pref': '#', - 'desc': 'Test Pattern' + "123": { + "uid": "123", + "pat": pattern, + "url": "https://r.io/i/${issue_id}", + "pref": "#", + "desc": "Test Pattern", } } - with mock.patch.object(IssueTrackerSettingsModel, - 'get_global_settings', get_settings_mock): - processed_text, issues, errors = helpers.process_patterns( - text_string, '') + with mock.patch.object(IssueTrackerSettingsModel, "get_global_settings", get_settings_mock): + processed_text, issues, errors = helpers.process_patterns(text_string, "") assert processed_text == expected_text def test_process_patterns_non_existent_repo_name(backend): - text_string = 'Fix #42' - pattern = r'(?:#)(?P\d+)' - expected_text = ('Fix #42') + text_string = "Fix #42" + pattern = r"(?:#)(?P\d+)" + expected_text = ( + 'Fix #42' + ) def get_settings_mock(self, cache=True): return { - '123': { - 'uid': '123', - 'pat': pattern, - 'url': 'https://r.io/${repo}/i/${issue_id}', - 'pref': '#', - 'desc': 'Test Pattern' + "123": { + "uid": "123", + "pat": pattern, + "url": "https://r.io/${repo}/i/${issue_id}", + "pref": "#", + "desc": "Test Pattern", } } - with mock.patch.object(IssueTrackerSettingsModel, - 'get_global_settings', get_settings_mock): - processed_text, issues, errors = helpers.process_patterns( - text_string, 'do-not-exist') + with mock.patch.object(IssueTrackerSettingsModel, "get_global_settings", get_settings_mock): + processed_text, issues, errors = helpers.process_patterns(text_string, "do-not-exist") assert processed_text == expected_text def test_get_visual_attr(baseapp): from rhodecode.apps._base import TemplateArgs + c = TemplateArgs() - assert None is helpers.get_visual_attr(c, 'fakse') + assert None is helpers.get_visual_attr(c, "fakse") # emulate the c.visual behaviour c.visual = AttributeDict({}) - assert None is helpers.get_visual_attr(c, 'some_var') + assert None is helpers.get_visual_attr(c, "some_var") - c.visual.some_var = 'foobar' - assert 'foobar' == helpers.get_visual_attr(c, 'some_var') + c.visual.some_var = "foobar" + assert "foobar" == helpers.get_visual_attr(c, "some_var") -@pytest.mark.parametrize('test_text, inclusive, expected_text', [ - ('just a string', False, 'just a string'), - ('just a string\n', False, 'just a string'), - ('just a string\n next line', False, 'just a string...'), - ('just a string\n next line', True, 'just a string\n...'), -], ids=no_newline_id_generator) +@pytest.mark.parametrize( + "test_text, inclusive, expected_text", + [ + ("just a string", False, "just a string"), + ("just a string\n", False, "just a string"), + ("just a string\n next line", False, "just a string..."), + ("just a string\n next line", True, "just a string\n..."), + ], + ids=no_newline_id_generator, +) def test_chop_at(test_text, inclusive, expected_text): - assert helpers.chop_at_smart( - test_text, '\n', inclusive, '...') == expected_text + assert helpers.chop_at_smart(test_text, "\n", inclusive, "...") == expected_text diff --git a/rhodecode/tests/lib/test_hooks_base.py b/rhodecode/tests/lib/test_hooks_base.py index 8f9bc781..dddde847 100644 --- a/rhodecode/tests/lib/test_hooks_base.py +++ b/rhodecode/tests/lib/test_hooks_base.py @@ -24,20 +24,20 @@ from rhodecode.lib import hooks_base, utils2 def test_post_push_truncates_commits(user_regular, repo_stub): extras = { - 'ip': '127.0.0.1', - 'username': user_regular.username, - 'user_id': user_regular.user_id, - 'action': 'push_local', - 'repository': repo_stub.repo_name, - 'scm': 'git', - 'config': '', - 'server_url': 'http://example.com', - 'make_lock': None, - 'user_agent': 'some-client', - 'locked_by': [None], - 'commit_ids': ['abcde12345' * 4] * 30000, - 'hook_type': 'large_push_test_type', - 'is_shadow_repo': False, + "ip": "127.0.0.1", + "username": user_regular.username, + "user_id": user_regular.user_id, + "action": "push_local", + "repository": repo_stub.repo_name, + "scm": "git", + "config": "", + "server_url": "http://example.com", + "make_lock": None, + "user_agent": "some-client", + "locked_by": [None], + "commit_ids": ["abcde12345" * 4] * 30000, + "hook_type": "large_push_test_type", + "is_shadow_repo": False, } extras = utils2.AttributeDict(extras) @@ -47,8 +47,8 @@ def test_post_push_truncates_commits(user_regular, repo_stub): commit_ids = extras.commit_ids[:400] entry = UserLog.query().order_by(UserLog.user_log_id.desc()).first() - assert entry.action == 'user.push' - assert entry.action_data['commit_ids'] == commit_ids + assert entry.action == "user.push" + assert entry.action_data["commit_ids"] == commit_ids Session().delete(entry) Session().commit() @@ -61,46 +61,50 @@ def assert_called_with_mock(callable_, expected_mock_name): @pytest.fixture() def hook_extras(user_regular, repo_stub): - extras = utils2.AttributeDict({ - 'ip': '127.0.0.1', - 'username': user_regular.username, - 'user_id': user_regular.user_id, - 'action': 'push', - 'repository': repo_stub.repo_name, - 'scm': '', - 'config': '', - 'repo_store': '', - 'server_url': 'http://example.com', - 'make_lock': None, - 'user_agent': 'some-client', - 'locked_by': [None], - 'commit_ids': [], - 'hook_type': 'test_type', - 'is_shadow_repo': False, - }) + extras = utils2.AttributeDict( + { + "ip": "127.0.0.1", + "username": user_regular.username, + "user_id": user_regular.user_id, + "action": "push", + "repository": repo_stub.repo_name, + "scm": "", + "config": "", + "repo_store": "", + "server_url": "http://example.com", + "make_lock": None, + "user_agent": "some-client", + "locked_by": [None], + "commit_ids": [], + "hook_type": "test_type", + "is_shadow_repo": False, + } + ) return extras class ExtensionMock(mock.Mock): - def __repr__(self): - return f'ExtensionMock({self._mock_name})' + return f"ExtensionMock({self._mock_name})" @property def output(self): - return 'MOCK' + return "MOCK" @property def status(self): return 0 -@pytest.mark.parametrize('func, extension, event', [ - (hooks_base.pre_push, 'pre_push_extension', 'RepoPrePushEvent'), - (hooks_base.post_push, 'post_push_extension', 'RepoPushEvent'), - (hooks_base.pre_pull, 'pre_pull_extension', 'RepoPrePullEvent'), - (hooks_base.post_pull, 'post_pull_extension', 'RepoPullEvent'), -]) +@pytest.mark.parametrize( + "func, extension, event", + [ + (hooks_base.pre_push, "pre_push_extension", "RepoPrePushEvent"), + (hooks_base.post_push, "post_push_extension", "RepoPushEvent"), + (hooks_base.pre_pull, "pre_pull_extension", "RepoPrePullEvent"), + (hooks_base.post_pull, "post_pull_extension", "RepoPullEvent"), + ], +) def test_hooks_propagate(func, extension, event, hook_extras): """ Tests that our hook code propagates to rhodecode extensions and triggers @@ -112,8 +116,8 @@ def test_hooks_propagate(func, extension, event, hook_extras): events_mock = mock.Mock() patches = { - 'Repository': mock.Mock(), - 'events': events_mock, + "Repository": mock.Mock(), + "events": events_mock, extension: extension_mock, } @@ -129,12 +133,15 @@ def test_hooks_propagate(func, extension, event, hook_extras): assert_called_with_mock(events_mock.trigger, event) -@pytest.mark.parametrize('func, extension, event', [ - (hooks_base.pre_push, 'pre_push_extension', 'RepoPrePushEvent'), - (hooks_base.post_push, 'post_push_extension', 'RepoPushEvent'), - (hooks_base.pre_pull, 'pre_pull_extension', 'RepoPrePullEvent'), - (hooks_base.post_pull, 'post_pull_extension', 'RepoPullEvent'), -]) +@pytest.mark.parametrize( + "func, extension, event", + [ + (hooks_base.pre_push, "pre_push_extension", "RepoPrePushEvent"), + (hooks_base.post_push, "post_push_extension", "RepoPushEvent"), + (hooks_base.pre_pull, "pre_pull_extension", "RepoPrePullEvent"), + (hooks_base.post_pull, "post_pull_extension", "RepoPullEvent"), + ], +) def test_hooks_propagates_not_on_shadow(func, extension, event, hook_extras): """ If hooks are called by a request to a shadow repo we only want to run our @@ -147,8 +154,8 @@ def test_hooks_propagates_not_on_shadow(func, extension, event, hook_extras): events_mock = mock.Mock() patches = { - 'Repository': mock.Mock(), - 'events': events_mock, + "Repository": mock.Mock(), + "events": events_mock, extension: extension_mock, } @@ -162,4 +169,3 @@ def test_hooks_propagates_not_on_shadow(func, extension, event, hook_extras): # Assert that extensions are *not* called and event was *not* fired. assert not extension_mock.called assert not events_mock.trigger.called - diff --git a/rhodecode/tests/lib/test_hooks_daemon.py b/rhodecode/tests/lib/test_hooks_daemon.py index 1e4e079e..cce6788a 100644 --- a/rhodecode/tests/lib/test_hooks_daemon.py +++ b/rhodecode/tests/lib/test_hooks_daemon.py @@ -36,63 +36,51 @@ class TestHooks(object): pass assert hooks == return_value -class TestPrepareHooksDaemon(object): - @pytest.mark.parametrize('protocol', ('celery',)) +class TestPrepareHooksDaemon(object): + @pytest.mark.parametrize("protocol", ("celery",)) def test_returns_celery_hooks_callback_daemon_when_celery_protocol_specified(self, protocol): - with tempfile.NamedTemporaryFile(mode='w') as temp_file: + with tempfile.NamedTemporaryFile(mode="w") as temp_file: temp_file.write( - "[app:main]\n" - "celery.broker_url = redis://redis/0\n" - "celery.result_backend = redis://redis/0\n" + "[app:main]\ncelery.broker_url = redis://redis/0\ncelery.result_backend = redis://redis/0\n" ) temp_file.flush() - expected_extras = {'config': temp_file.name} + expected_extras = {"config": temp_file.name} callback, extras = hooks_utils.prepare_callback_daemon(expected_extras, protocol=protocol) assert isinstance(callback, celery_hooks_deamon.CeleryHooksCallbackDaemon) - @pytest.mark.parametrize('protocol, expected_class', ( - ('celery', celery_hooks_deamon.CeleryHooksCallbackDaemon), - )) + @pytest.mark.parametrize("protocol, expected_class", (("celery", celery_hooks_deamon.CeleryHooksCallbackDaemon),)) def test_returns_real_hooks_callback_daemon_when_protocol_is_specified(self, protocol, expected_class): - - with tempfile.NamedTemporaryFile(mode='w') as temp_file: + with tempfile.NamedTemporaryFile(mode="w") as temp_file: temp_file.write( - "[app:main]\n" - "celery.broker_url = redis://redis:6379/0\n" - "celery.result_backend = redis://redis:6379/0\n" + "[app:main]\ncelery.broker_url = redis://redis:6379/0\ncelery.result_backend = redis://redis:6379/0\n" ) temp_file.flush() expected_extras = { - 'extra1': 'value1', - 'txn_id': 'txnid2', - 'hooks_protocol': protocol.lower(), - 'hooks_config': { - 'broker_url': 'redis://redis:6379/0', - 'result_backend': 'redis://redis:6379/0', + "extra1": "value1", + "txn_id": "txnid2", + "hooks_protocol": protocol.lower(), + "hooks_config": { + "broker_url": "redis://redis:6379/0", + "result_backend": "redis://redis:6379/0", }, - 'repo_store': '/var/opt/rhodecode_repo_store', - 'repository': 'rhodecode', - 'config': temp_file.name + "repo_store": "/var/opt/rhodecode_repo_store", + "repository": "rhodecode", + "config": temp_file.name, } from rhodecode import CONFIG - CONFIG['vcs.svn.redis_conn'] = 'redis://redis:6379/0' - callback, extras = hooks_utils.prepare_callback_daemon(expected_extras.copy(), protocol=protocol,txn_id='txnid2') + + CONFIG["vcs.svn.redis_conn"] = "redis://redis:6379/0" + callback, extras = hooks_utils.prepare_callback_daemon( + expected_extras.copy(), protocol=protocol, txn_id="txnid2" + ) assert isinstance(callback, expected_class) - expected_extras['time'] = extras['time'] + expected_extras["time"] = extras["time"] assert extras == expected_extras - @pytest.mark.parametrize('protocol', ( - 'invalid', - 'Http', - 'HTTP', - 'celerY' - )) + @pytest.mark.parametrize("protocol", ("invalid", "Http", "HTTP", "celerY")) def test_raises_on_invalid_protocol(self, protocol): - expected_extras = { - 'extra1': 'value1', - 'hooks_protocol': protocol.lower() - } + expected_extras = {"extra1": "value1", "hooks_protocol": protocol.lower()} with pytest.raises(Exception): callback, extras = hooks_utils.prepare_callback_daemon(expected_extras.copy(), protocol=protocol) diff --git a/rhodecode/tests/lib/test_html_sanitizer.py b/rhodecode/tests/lib/test_html_sanitizer.py index 5f7ea371..acf5ef90 100644 --- a/rhodecode/tests/lib/test_html_sanitizer.py +++ b/rhodecode/tests/lib/test_html_sanitizer.py @@ -24,14 +24,15 @@ from rhodecode.lib.html_filters import sanitize_html @pytest.mark.parametrize( "src_html, expected_html", [ - ('
ITEM
', '
ITEM
'), - ('
ITEM
', '
ITEM
'), + ("
ITEM
", "
ITEM
"), + ("
ITEM
", "
ITEM
"), ('
ITEM
', '
ITEM
'), - ('
ITEM
', '
ITEM
'), + ('
ITEM
', "
ITEM
"), ('ITEM', 'ITEM'), ('', ''), ('', ''), - ]) + ], +) def test_html_sanitizer_options(src_html, expected_html): parsed_html = sanitize_html(src_html) assert parsed_html == expected_html diff --git a/rhodecode/tests/lib/test_jsonalchemy.py b/rhodecode/tests/lib/test_jsonalchemy.py index 21fa29ba..3da75917 100644 --- a/rhodecode/tests/lib/test_jsonalchemy.py +++ b/rhodecode/tests/lib/test_jsonalchemy.py @@ -23,13 +23,12 @@ from sqlalchemy import Column, String, create_engine from sqlalchemy.orm import sessionmaker from sqlalchemy.ext.declarative import declarative_base -from rhodecode.lib.jsonalchemy import ( - MutationDict, MutationList, MutationObj, JsonType) +from rhodecode.lib.jsonalchemy import MutationDict, MutationList, MutationObj, JsonType @pytest.fixture() def engine(): - return create_engine('sqlite://') + return create_engine("sqlite://") @pytest.fixture() @@ -38,23 +37,21 @@ def session(engine): def test_mutation_dict_is_picklable(): - mutation_dict = MutationDict({'key1': 'value1', 'key2': 'value2'}) + mutation_dict = MutationDict({"key1": "value1", "key2": "value2"}) dumped = pickle.dumps(mutation_dict) loaded = pickle.loads(dumped) assert loaded == mutation_dict def test_mutation_list_is_picklable(): - mutation_list = MutationList(['a', 'b', 'c']) + mutation_list = MutationList(["a", "b", "c"]) dumped = pickle.dumps(mutation_list) loaded = pickle.loads(dumped) assert loaded == mutation_list def test_mutation_dict_with_lists_is_picklable(): - mutation_dict = MutationDict({ - 'key': MutationList(['values', MutationDict({'key': 'value'})]) - }) + mutation_dict = MutationDict({"key": MutationList(["values", MutationDict({"key": "value"})])}) dumped = pickle.dumps(mutation_dict) loaded = pickle.loads(dumped) assert loaded == mutation_dict @@ -69,37 +66,32 @@ def test_mutation_types_with_nullable(engine, session): Base = declarative_base() class DummyModel(Base): - __tablename__ = 'some_table' + __tablename__ = "some_table" name = Column(String, primary_key=True) - json_list = Column(MutationList.as_mutable(JsonType('list'))) - json_dict = Column(MutationDict.as_mutable(JsonType('dict'))) + json_list = Column(MutationList.as_mutable(JsonType("list"))) + json_dict = Column(MutationDict.as_mutable(JsonType("dict"))) json_obj = Column(MutationObj.as_mutable(JsonType())) Base.metadata.create_all(engine) - obj_nulls = DummyModel(name='nulls') - obj_stuff = DummyModel( - name='stuff', json_list=[1, 2, 3], json_dict={'a': 5}, json_obj=9) + obj_nulls = DummyModel(name="nulls") + obj_stuff = DummyModel(name="stuff", json_list=[1, 2, 3], json_dict={"a": 5}, json_obj=9) session.add(obj_nulls) session.add(obj_stuff) session.commit() session.expire_all() - assert engine.execute( - "select * from some_table where name = 'nulls';").first() == ( - ('nulls', None, None, None) - ) - ret_nulls = session.query(DummyModel).get('nulls') + assert engine.execute("select * from some_table where name = 'nulls';").first() == (("nulls", None, None, None)) + ret_nulls = session.query(DummyModel).get("nulls") assert ret_nulls.json_list == [] assert ret_nulls.json_dict == {} assert ret_nulls.json_obj is None - assert engine.execute( - "select * from some_table where name = 'stuff';").first() == ( - ('stuff', '[1,2,3]', '{"a":5}', '9') + assert engine.execute("select * from some_table where name = 'stuff';").first() == ( + ("stuff", "[1,2,3]", '{"a":5}', "9") ) - ret_stuff = session.query(DummyModel).get('stuff') + ret_stuff = session.query(DummyModel).get("stuff") assert ret_stuff.json_list == [1, 2, 3] - assert ret_stuff.json_dict == {'a': 5} + assert ret_stuff.json_dict == {"a": 5} assert ret_stuff.json_obj == 9 diff --git a/rhodecode/tests/lib/test_libs.py b/rhodecode/tests/lib/test_libs.py index f93d1a0c..446727e4 100644 --- a/rhodecode/tests/lib/test_libs.py +++ b/rhodecode/tests/lib/test_libs.py @@ -39,108 +39,135 @@ from rhodecode.model.db import Repository, CacheKey TEST_URLS = [ - ('127.0.0.1', '127.0.0.1'), - ('marcink@127.0.0.1', '127.0.0.1'), - ('marcink:pass@127.0.0.1', '127.0.0.1'), - ('marcink@domain.name:pass@127.0.0.1', '127.0.0.1'), - - ('127.0.0.1:8080', '127.0.0.1:8080'), - ('marcink@127.0.0.1:8080', '127.0.0.1:8080'), - ('marcink:pass@127.0.0.1:8080', '127.0.0.1:8080'), - ('marcink@domain.name:pass@127.0.0.1:8080', '127.0.0.1:8080'), - - ('domain.org', 'domain.org'), - ('user:pass@domain.org:8080', 'domain.org:8080'), - ('user@domain.org:pass@domain.org:8080', 'domain.org:8080'), - ] + ("127.0.0.1", "127.0.0.1"), + ("marcink@127.0.0.1", "127.0.0.1"), + ("marcink:pass@127.0.0.1", "127.0.0.1"), + ("marcink@domain.name:pass@127.0.0.1", "127.0.0.1"), + ("127.0.0.1:8080", "127.0.0.1:8080"), + ("marcink@127.0.0.1:8080", "127.0.0.1:8080"), + ("marcink:pass@127.0.0.1:8080", "127.0.0.1:8080"), + ("marcink@domain.name:pass@127.0.0.1:8080", "127.0.0.1:8080"), + ("domain.org", "domain.org"), + ("user:pass@domain.org:8080", "domain.org:8080"), + ("user@domain.org:pass@domain.org:8080", "domain.org:8080"), +] -@pytest.mark.parametrize("protocol", ['http://', 'https://']) +@pytest.mark.parametrize("protocol", ["http://", "https://"]) @pytest.mark.parametrize("test_url, expected", TEST_URLS) def test_credentials_filter(protocol, test_url, expected): from rhodecode.lib.utils2 import credentials_filter + test_url = protocol + test_url assert credentials_filter(test_url) == protocol + expected -@pytest.mark.parametrize("str_bool, expected", [ - ('t', True), - ('true', True), - ('y', True), - ('yes', True), - ('on', True), - ('1', True), - ('Y', True), - ('yeS', True), - ('Y', True), - ('TRUE', True), - ('T', True), - ('False', False), - ('F', False), - ('FALSE', False), - ('0', False), - ('-1', False), - ('', False) -]) +@pytest.mark.parametrize( + "str_bool, expected", + [ + ("t", True), + ("true", True), + ("y", True), + ("yes", True), + ("on", True), + ("1", True), + ("Y", True), + ("yeS", True), + ("Y", True), + ("TRUE", True), + ("T", True), + ("False", False), + ("F", False), + ("FALSE", False), + ("0", False), + ("-1", False), + ("", False), + ], +) def test_str2bool(str_bool, expected): from rhodecode.lib.utils2 import str2bool + assert str2bool(str_bool) == expected -@pytest.mark.parametrize("text, expected", functools.reduce(lambda a1, a2: a1+a2, [ -[ -(pref+"", []), -(pref+"Hi there @marcink", ['marcink']), -(pref+"Hi there @marcink and @bob", ['bob', 'marcink']), -(pref+"Hi there @marcink\n", ['marcink']), -(pref+"Hi there @marcink and @bob\n", ['bob', 'marcink']), -(pref+"Hi there marcin@rhodecode.com", []), -(pref+"Hi there @john.malcovic and @bob\n", ['bob', 'john.malcovic']), -(pref+"This needs to be reviewed: (@marcink,@john)", ["john", "marcink"]), -(pref+"This needs to be reviewed: (@marcink, @john)", ["john", "marcink"]), -(pref+"This needs to be reviewed: [@marcink,@john]", ["john", "marcink"]), -(pref+"This needs to be reviewed: (@marcink @john)", ["john", "marcink"]), -(pref+"@john @mary, please review", ["john", "mary"]), -(pref+"@john,@mary, please review", ["john", "mary"]), -(pref+"Hej @123, @22john,@mary, please review", ['123', '22john', 'mary']), -(pref+"@first hi there @marcink here's my email marcin@email.com " - "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three ", ['first', 'lukaszb', 'marcink', 'one', 'one_more22']), -(pref+"@MARCIN @maRCiN @2one_more22 @john please see this http://org.pl", ['2one_more22', 'john', 'MARCIN', 'maRCiN']), -(pref+"@marian.user just do it @marco-polo and next extract @marco_polo", ['marco-polo', 'marco_polo', 'marian.user']), -(pref+"user.dot hej ! not-needed maril@domain.org", []), -(pref+"\n@marcin", ['marcin']), -] -for pref in ['', '\n', 'hi !', '\t', '\n\n']]), ids=no_newline_id_generator) +@pytest.mark.parametrize( + "text, expected", + functools.reduce( + lambda a1, a2: a1 + a2, + [ + [ + (pref + "", []), + (pref + "Hi there @marcink", ["marcink"]), + (pref + "Hi there @marcink and @bob", ["bob", "marcink"]), + (pref + "Hi there @marcink\n", ["marcink"]), + (pref + "Hi there @marcink and @bob\n", ["bob", "marcink"]), + (pref + "Hi there marcin@rhodecode.com", []), + (pref + "Hi there @john.malcovic and @bob\n", ["bob", "john.malcovic"]), + (pref + "This needs to be reviewed: (@marcink,@john)", ["john", "marcink"]), + (pref + "This needs to be reviewed: (@marcink, @john)", ["john", "marcink"]), + (pref + "This needs to be reviewed: [@marcink,@john]", ["john", "marcink"]), + (pref + "This needs to be reviewed: (@marcink @john)", ["john", "marcink"]), + (pref + "@john @mary, please review", ["john", "mary"]), + (pref + "@john,@mary, please review", ["john", "mary"]), + (pref + "Hej @123, @22john,@mary, please review", ["123", "22john", "mary"]), + ( + pref + "@first hi there @marcink here's my email marcin@email.com " + "@lukaszb check @one_more22 it pls @ ttwelve @D[] @one@two@three ", + ["first", "lukaszb", "marcink", "one", "one_more22"], + ), + ( + pref + "@MARCIN @maRCiN @2one_more22 @john please see this http://org.pl", + ["2one_more22", "john", "MARCIN", "maRCiN"], + ), + ( + pref + "@marian.user just do it @marco-polo and next extract @marco_polo", + ["marco-polo", "marco_polo", "marian.user"], + ), + (pref + "user.dot hej ! not-needed maril@domain.org", []), + (pref + "\n@marcin", ["marcin"]), + ] + for pref in ["", "\n", "hi !", "\t", "\n\n"] + ], + ), + ids=no_newline_id_generator, +) def test_mention_extractor(text, expected): from rhodecode.lib.utils2 import extract_mentioned_users + got = extract_mentioned_users(text) assert sorted(got, key=lambda x: x.lower()) == got assert set(expected) == set(got) -@pytest.mark.parametrize("age_args, expected, kw", [ - ({}, u'just now', {}), - ({'seconds': -1}, u'1 second ago', {}), - ({'seconds': -60 * 2}, u'2 minutes ago', {}), - ({'hours': -1}, u'1 hour ago', {}), - ({'hours': -24}, u'1 day ago', {}), - ({'hours': -24 * 5}, u'5 days ago', {}), - ({'months': -1}, u'1 month ago', {}), - ({'months': -1, 'days': -2}, u'1 month and 2 days ago', {}), - ({'years': -1, 'months': -1}, u'1 year and 1 month ago', {}), - ({}, u'just now', {'short_format': True}), - ({'seconds': -1}, u'1sec ago', {'short_format': True}), - ({'seconds': -60 * 2}, u'2min ago', {'short_format': True}), - ({'hours': -1}, u'1h ago', {'short_format': True}), - ({'hours': -24}, u'1d ago', {'short_format': True}), - ({'hours': -24 * 5}, u'5d ago', {'short_format': True}), - ({'months': -1}, u'1m ago', {'short_format': True}), - ({'months': -1, 'days': -2}, u'1m, 2d ago', {'short_format': True}), - ({'years': -1, 'months': -1}, u'1y, 1m ago', {'short_format': True}), -]) + +@pytest.mark.parametrize( + "age_args, expected, kw", + [ + ({}, "just now", {}), + ({"seconds": -1}, "1 second ago", {}), + ({"seconds": -60 * 2}, "2 minutes ago", {}), + ({"hours": -1}, "1 hour ago", {}), + ({"hours": -24}, "1 day ago", {}), + ({"hours": -24 * 5}, "5 days ago", {}), + ({"months": -1}, "1 month ago", {}), + ({"months": -1, "days": -2}, "1 month and 2 days ago", {}), + ({"years": -1, "months": -1}, "1 year and 1 month ago", {}), + ({}, "just now", {"short_format": True}), + ({"seconds": -1}, "1sec ago", {"short_format": True}), + ({"seconds": -60 * 2}, "2min ago", {"short_format": True}), + ({"hours": -1}, "1h ago", {"short_format": True}), + ({"hours": -24}, "1d ago", {"short_format": True}), + ({"hours": -24 * 5}, "5d ago", {"short_format": True}), + ({"months": -1}, "1m ago", {"short_format": True}), + ({"months": -1, "days": -2}, "1m, 2d ago", {"short_format": True}), + ({"years": -1, "months": -1}, "1y, 1m ago", {"short_format": True}), + ], +) def test_age(age_args, expected, kw, baseapp): from rhodecode.lib.utils2 import age from dateutil import relativedelta + n = datetime.datetime(year=2012, month=5, day=17) + def delt(*args, **kwargs): return relativedelta.relativedelta(*args, **kwargs) @@ -150,30 +177,35 @@ def test_age(age_args, expected, kw, baseapp): assert translate(age(n + delt(**age_args), now=n, **kw)) == expected -@pytest.mark.parametrize("age_args, expected, kw", [ - ({}, u'just now', {}), - ({'seconds': 1}, u'in 1 second', {}), - ({'seconds': 60 * 2}, u'in 2 minutes', {}), - ({'hours': 1}, u'in 1 hour', {}), - ({'hours': 24}, u'in 1 day', {}), - ({'hours': 24 * 5}, u'in 5 days', {}), - ({'months': 1}, u'in 1 month', {}), - ({'months': 1, 'days': 1}, u'in 1 month and 1 day', {}), - ({'years': 1, 'months': 1}, u'in 1 year and 1 month', {}), - ({}, u'just now', {'short_format': True}), - ({'seconds': 1}, u'in 1sec', {'short_format': True}), - ({'seconds': 60 * 2}, u'in 2min', {'short_format': True}), - ({'hours': 1}, u'in 1h', {'short_format': True}), - ({'hours': 24}, u'in 1d', {'short_format': True}), - ({'hours': 24 * 5}, u'in 5d', {'short_format': True}), - ({'months': 1}, u'in 1m', {'short_format': True}), - ({'months': 1, 'days': 1}, u'in 1m, 1d', {'short_format': True}), - ({'years': 1, 'months': 1}, u'in 1y, 1m', {'short_format': True}), -]) +@pytest.mark.parametrize( + "age_args, expected, kw", + [ + ({}, "just now", {}), + ({"seconds": 1}, "in 1 second", {}), + ({"seconds": 60 * 2}, "in 2 minutes", {}), + ({"hours": 1}, "in 1 hour", {}), + ({"hours": 24}, "in 1 day", {}), + ({"hours": 24 * 5}, "in 5 days", {}), + ({"months": 1}, "in 1 month", {}), + ({"months": 1, "days": 1}, "in 1 month and 1 day", {}), + ({"years": 1, "months": 1}, "in 1 year and 1 month", {}), + ({}, "just now", {"short_format": True}), + ({"seconds": 1}, "in 1sec", {"short_format": True}), + ({"seconds": 60 * 2}, "in 2min", {"short_format": True}), + ({"hours": 1}, "in 1h", {"short_format": True}), + ({"hours": 24}, "in 1d", {"short_format": True}), + ({"hours": 24 * 5}, "in 5d", {"short_format": True}), + ({"months": 1}, "in 1m", {"short_format": True}), + ({"months": 1, "days": 1}, "in 1m, 1d", {"short_format": True}), + ({"years": 1, "months": 1}, "in 1y, 1m", {"short_format": True}), + ], +) def test_age_in_future(age_args, expected, kw, baseapp): from rhodecode.lib.utils2 import age from dateutil import relativedelta + n = datetime.datetime(year=2012, month=5, day=17) + def delt(*args, **kwargs): return relativedelta.relativedelta(*args, **kwargs) @@ -183,154 +215,203 @@ def test_age_in_future(age_args, expected, kw, baseapp): assert translate(age(n + delt(**age_args), now=n, **kw)) == expected -@pytest.mark.parametrize("sample, expected_tags", [ - # entry - (( - "" - ), - [ - - ]), - # entry - (( - "hello world [stale]" - ), - [ - ('state', '[stale]'), - ]), - # entry - (( - "hello world [v2.0.0] [v1.0.0]" - ), - [ - ('generic', '[v2.0.0]'), - ('generic', '[v1.0.0]'), - ]), - # entry - (( - "he[ll]o wo[rl]d" - ), - [ - ('label', '[ll]'), - ('label', '[rl]'), - ]), - # entry - (( - "hello world [stale]\n[featured]\n[stale] [dead] [dev]" - ), - [ - ('state', '[stale]'), - ('state', '[featured]'), - ('state', '[stale]'), - ('state', '[dead]'), - ('state', '[dev]'), - ]), - # entry - (( - "hello world \n\n [stale] \n [url => [name](http://rc.com)]" - ), - [ - ('state', '[stale]'), - ('url', '[url => [name](http://rc.com)]'), - ]), - # entry - (( - "[url => [linkNameJS](javascript:alert(document.domain))]\n" - "[url => [linkNameHTTP](http://rhodecode.com)]\n" - "[url => [linkNameHTTPS](https://rhodecode.com)]\n" - "[url => [linkNamePath](/repo_group)]\n" - ), - [ - ('generic', '[linkNameJS]'), - ('url', '[url => [linkNameHTTP](http://rhodecode.com)]'), - ('url', '[url => [linkNameHTTPS](https://rhodecode.com)]'), - ('url', '[url => [linkNamePath](/repo_group)]'), - ]), - # entry - (( - "hello pta[tag] gog [[]] [[] sda ero[or]d [me =>>< sa]" - "[requires] [stale] [see<>=>] [see => http://url.com]" - "[requires => url] [lang => python] [just a tag] " - "" - "[,d] [ => ULR ] [obsolete] [desc]]" - ), - [ - ('label', '[desc]'), - ('label', '[obsolete]'), - ('label', '[or]'), - ('label', '[requires]'), - ('label', '[tag]'), - ('state', '[stale]'), - ('lang', '[lang => python]'), - ('ref', '[requires => url]'), - ('see', '[see => http://url.com]'), - - ]), - -], ids=no_newline_id_generator) +@pytest.mark.parametrize( + "sample, expected_tags", + [ + # entry + ((""), []), + # entry + ( + ("hello world [stale]"), + [ + ("state", "[stale]"), + ], + ), + # entry + ( + ("hello world [v2.0.0] [v1.0.0]"), + [ + ("generic", "[v2.0.0]"), + ("generic", "[v1.0.0]"), + ], + ), + # entry + ( + ("he[ll]o wo[rl]d"), + [ + ("label", "[ll]"), + ("label", "[rl]"), + ], + ), + # entry + ( + ("hello world [stale]\n[featured]\n[stale] [dead] [dev]"), + [ + ("state", "[stale]"), + ("state", "[featured]"), + ("state", "[stale]"), + ("state", "[dead]"), + ("state", "[dev]"), + ], + ), + # entry + ( + ("hello world \n\n [stale] \n [url => [name](http://rc.com)]"), + [ + ("state", "[stale]"), + ("url", "[url => [name](http://rc.com)]"), + ], + ), + # entry + ( + ( + "[url => [linkNameJS](javascript:alert(document.domain))]\n" + "[url => [linkNameHTTP](http://rhodecode.com)]\n" + "[url => [linkNameHTTPS](https://rhodecode.com)]\n" + "[url => [linkNamePath](/repo_group)]\n" + ), + [ + ("generic", "[linkNameJS]"), + ("url", "[url => [linkNameHTTP](http://rhodecode.com)]"), + ("url", "[url => [linkNameHTTPS](https://rhodecode.com)]"), + ("url", "[url => [linkNamePath](/repo_group)]"), + ], + ), + # entry + ( + ( + "hello pta[tag] gog [[]] [[] sda ero[or]d [me =>>< sa]" + "[requires] [stale] [see<>=>] [see => http://url.com]" + "[requires => url] [lang => python] [just a tag] " + "" + "[,d] [ => ULR ] [obsolete] [desc]]" + ), + [ + ("label", "[desc]"), + ("label", "[obsolete]"), + ("label", "[or]"), + ("label", "[requires]"), + ("label", "[tag]"), + ("state", "[stale]"), + ("lang", "[lang => python]"), + ("ref", "[requires => url]"), + ("see", "[see => http://url.com]"), + ], + ), + ], + ids=no_newline_id_generator, +) def test_metatag_extraction(sample, expected_tags): from rhodecode.lib.helpers import extract_metatags + tags, value = extract_metatags(sample) assert sorted(tags) == sorted(expected_tags) -@pytest.mark.parametrize("tag_data, expected_html", [ - - (('state', '[stable]'), '
stable
'), - (('state', '[stale]'), '
stale
'), - (('state', '[featured]'), '
featured
'), - (('state', '[dev]'), '
dev
'), - (('state', '[dead]'), '
dead
'), - - (('label', '[personal]'), '
personal
'), - (('generic', '[v2.0.0]'), '
v2.0.0
'), - - (('lang', '[lang => JavaScript]'), '
JavaScript
'), - (('lang', '[lang => C++]'), '
C++
'), - (('lang', '[lang => C#]'), '
C#
'), - (('lang', '[lang => Delphi/Object]'), '
Delphi/Object
'), - (('lang', '[lang => Objective-C]'), '
Objective-C
'), - (('lang', '[lang => .NET]'), '
.NET
'), - - (('license', '[license => BSD 3-clause]'), ''), - (('license', '[license => GPLv3]'), ''), - (('license', '[license => MIT]'), ''), - (('license', '[license => AGPLv3]'), ''), - - (('ref', '[requires => RepoName]'), '
requires: RepoName
'), - (('ref', '[recommends => GroupName]'), '
recommends: GroupName
'), - (('ref', '[conflicts => SomeName]'), '
conflicts: SomeName
'), - (('ref', '[base => SomeName]'), '
base: SomeName
'), - - (('see', '[see => http://rhodecode.com]'), '
see: http://rhodecode.com
'), - - (('url', '[url => [linkName](https://rhodecode.com)]'), ''), - (('url', '[url => [example link](https://rhodecode.com)]'), ''), - (('url', '[url => [v1.0.0](https://rhodecode.com)]'), ''), - -]) +@pytest.mark.parametrize( + "tag_data, expected_html", + [ + (("state", "[stable]"), '
stable
'), + (("state", "[stale]"), '
stale
'), + (("state", "[featured]"), '
featured
'), + (("state", "[dev]"), '
dev
'), + (("state", "[dead]"), '
dead
'), + (("label", "[personal]"), '
personal
'), + (("generic", "[v2.0.0]"), '
v2.0.0
'), + (("lang", "[lang => JavaScript]"), '
JavaScript
'), + (("lang", "[lang => C++]"), '
C++
'), + (("lang", "[lang => C#]"), '
C#
'), + (("lang", "[lang => Delphi/Object]"), '
Delphi/Object
'), + (("lang", "[lang => Objective-C]"), '
Objective-C
'), + (("lang", "[lang => .NET]"), '
.NET
'), + ( + ("license", "[license => BSD 3-clause]"), + '', + ), + ( + ("license", "[license => GPLv3]"), + '', + ), + ( + ("license", "[license => MIT]"), + '', + ), + ( + ("license", "[license => AGPLv3]"), + '', + ), + ( + ("ref", "[requires => RepoName]"), + '
requires: RepoName
', + ), + ( + ("ref", "[recommends => GroupName]"), + '
recommends: GroupName
', + ), + ( + ("ref", "[conflicts => SomeName]"), + '
conflicts: SomeName
', + ), + ( + ("ref", "[base => SomeName]"), + '
base: SomeName
', + ), + ( + ("see", "[see => http://rhodecode.com]"), + '
see: http://rhodecode.com
', + ), + ( + ("url", "[url => [linkName](https://rhodecode.com)]"), + '', + ), + ( + ("url", "[url => [example link](https://rhodecode.com)]"), + '', + ), + ( + ("url", "[url => [v1.0.0](https://rhodecode.com)]"), + '', + ), + ], +) def test_metatags_stylize(tag_data, expected_html): from rhodecode.lib.helpers import style_metatag - tag_type,value = tag_data + + tag_type, value = tag_data assert style_metatag(tag_type, value) == expected_html -@pytest.mark.parametrize("tmpl_url, email, expected", [ - ('http://test.com/{email}', 'test@foo.com', 'http://test.com/test@foo.com'), - - ('http://test.com/{md5email}', 'test@foo.com', 'http://test.com/3cb7232fcc48743000cb86d0d5022bd9'), - ('http://test.com/{md5email}', 'testąć@foo.com', 'http://test.com/978debb907a3c55cd741872ab293ef30'), - - ('http://testX.com/{md5email}?s={size}', 'test@foo.com', 'http://testX.com/3cb7232fcc48743000cb86d0d5022bd9?s=24'), - ('http://testX.com/{md5email}?s={size}', 'testąć@foo.com', 'http://testX.com/978debb907a3c55cd741872ab293ef30?s=24'), - - ('{scheme}://{netloc}/{md5email}/{size}', 'test@foo.com', 'https://server.com/3cb7232fcc48743000cb86d0d5022bd9/24'), - ('{scheme}://{netloc}/{md5email}/{size}', 'testąć@foo.com', 'https://server.com/978debb907a3c55cd741872ab293ef30/24'), - - ('http://test.com/{email}', 'testąć@foo.com', 'http://test.com/testąć@foo.com'), - ('http://test.com/{email}?size={size}', 'test@foo.com', 'http://test.com/test@foo.com?size=24'), - ('http://test.com/{email}?size={size}', 'testąć@foo.com', 'http://test.com/testąć@foo.com?size=24'), -]) +@pytest.mark.parametrize( + "tmpl_url, email, expected", + [ + ("http://test.com/{email}", "test@foo.com", "http://test.com/test@foo.com"), + ("http://test.com/{md5email}", "test@foo.com", "http://test.com/3cb7232fcc48743000cb86d0d5022bd9"), + ("http://test.com/{md5email}", "testąć@foo.com", "http://test.com/978debb907a3c55cd741872ab293ef30"), + ( + "http://testX.com/{md5email}?s={size}", + "test@foo.com", + "http://testX.com/3cb7232fcc48743000cb86d0d5022bd9?s=24", + ), + ( + "http://testX.com/{md5email}?s={size}", + "testąć@foo.com", + "http://testX.com/978debb907a3c55cd741872ab293ef30?s=24", + ), + ( + "{scheme}://{netloc}/{md5email}/{size}", + "test@foo.com", + "https://server.com/3cb7232fcc48743000cb86d0d5022bd9/24", + ), + ( + "{scheme}://{netloc}/{md5email}/{size}", + "testąć@foo.com", + "https://server.com/978debb907a3c55cd741872ab293ef30/24", + ), + ("http://test.com/{email}", "testąć@foo.com", "http://test.com/testąć@foo.com"), + ("http://test.com/{email}?size={size}", "test@foo.com", "http://test.com/test@foo.com?size=24"), + ("http://test.com/{email}?size={size}", "testąć@foo.com", "http://test.com/testąć@foo.com?size=24"), + ], +) def test_gravatar_url_builder(tmpl_url, email, expected, request_stub): from rhodecode.lib.helpers import gravatar_url @@ -343,52 +424,48 @@ def test_gravatar_url_builder(tmpl_url, email, expected, request_stub): # mock pyramid.threadlocals def fake_get_current_request(): - request_stub.scheme = 'https' - request_stub.host = 'server.com' + request_stub.scheme = "https" + request_stub.host = "server.com" request_stub._call_context = fake_tmpl_context(tmpl_url) return request_stub - with mock.patch('rhodecode.lib.helpers.get_current_request', - fake_get_current_request): - + with mock.patch("rhodecode.lib.helpers.get_current_request", fake_get_current_request): grav = gravatar_url(email_address=email, size=24) assert grav == expected @pytest.mark.parametrize( - "email, first_name, last_name, expected_initials, expected_color", [ - - ('test@rhodecode.com', '', '', 'TR', '#8a994d'), - ('marcin.kuzminski@rhodecode.com', '', '', 'MK', '#6559b3'), + "email, first_name, last_name, expected_initials, expected_color", + [ + ("test@rhodecode.com", "", "", "TR", "#8a994d"), + ("marcin.kuzminski@rhodecode.com", "", "", "MK", "#6559b3"), # special cases of email - ('john.van.dam@rhodecode.com', '', '', 'JD', '#526600'), - ('Guido.van.Rossum@rhodecode.com', '', '', 'GR', '#990052'), - ('Guido.van.Rossum@rhodecode.com', 'Guido', 'Van Rossum', 'GR', '#990052'), - - ('rhodecode+Guido.van.Rossum@rhodecode.com', '', '', 'RR', '#46598c'), - ('pclouds@rhodecode.com', 'Nguyễn Thái', 'Tgọc Duy', 'ND', '#665200'), - - ('john-brown@foo.com', '', '', 'JF', '#73006b'), - ('admin@rhodecode.com', 'Marcin', 'Kuzminski', 'MK', '#104036'), + ("john.van.dam@rhodecode.com", "", "", "JD", "#526600"), + ("Guido.van.Rossum@rhodecode.com", "", "", "GR", "#990052"), + ("Guido.van.Rossum@rhodecode.com", "Guido", "Van Rossum", "GR", "#990052"), + ("rhodecode+Guido.van.Rossum@rhodecode.com", "", "", "RR", "#46598c"), + ("pclouds@rhodecode.com", "Nguyễn Thái", "Tgọc Duy", "ND", "#665200"), + ("john-brown@foo.com", "", "", "JF", "#73006b"), + ("admin@rhodecode.com", "Marcin", "Kuzminski", "MK", "#104036"), # partials - ('admin@rhodecode.com', 'Marcin', '', 'MR', '#104036'), # fn+email - ('admin@rhodecode.com', '', 'Kuzminski', 'AK', '#104036'), # em+ln + ("admin@rhodecode.com", "Marcin", "", "MR", "#104036"), # fn+email + ("admin@rhodecode.com", "", "Kuzminski", "AK", "#104036"), # em+ln # non-ascii - ('admin@rhodecode.com', 'Marcin', 'Śuzminski', 'MS', '#104036'), - ('admin@rhodecode.com', 'Łukasz', 'Śuzminski', 'LS', '#104036'), - ('admin@rhodecode.com', 'Fabian', 'Łukaszewski', 'FL', '#104036'), - - ('marcin.śuzminski@rhodecode.com', '', '', 'MS', '#73000f'), - + ("admin@rhodecode.com", "Marcin", "Śuzminski", "MS", "#104036"), + ("admin@rhodecode.com", "Łukasz", "Śuzminski", "LS", "#104036"), + ("admin@rhodecode.com", "Fabian", "Łukaszewski", "FL", "#104036"), + ("marcin.śuzminski@rhodecode.com", "", "", "MS", "#73000f"), # special cases, LDAP can provide those... - ('admin@', 'Marcin', 'Śuzminski', 'MS', '#aa00ff'), - ('marcin.śuzminski', '', '', 'MS', '#402020'), - ('null', '', '', 'NL', '#8c4646'), - ('some.@abc.com', 'some', '', 'SA', '#664e33') -]) + ("admin@", "Marcin", "Śuzminski", "MS", "#aa00ff"), + ("marcin.śuzminski", "", "", "MS", "#402020"), + ("null", "", "", "NL", "#8c4646"), + ("some.@abc.com", "some", "", "SA", "#664e33"), + ], +) def test_initials_gravatar_pick_of_initials_and_color_algo( - email, first_name, last_name, expected_initials, expected_color): + email, first_name, last_name, expected_initials, expected_color +): instance = InitialsGravatar(email, first_name, last_name) assert instance.get_initials() == expected_initials assert instance.str2color(email) == expected_color @@ -396,22 +473,19 @@ def test_initials_gravatar_pick_of_initials_and_color_algo( def test_initials_gravatar_mapping_algo(): pos = set() - instance = InitialsGravatar('', '', '') + instance = InitialsGravatar("", "", "") iterations = 0 variations = [] for letter1 in string.ascii_letters: for letter2 in string.ascii_letters[::-1][:10]: for letter3 in string.ascii_letters[:10]: - variations.append( - '%s@rhodecode.com' % (letter1+letter2+letter3)) + variations.append("%s@rhodecode.com" % (letter1 + letter2 + letter3)) max_variations = 4096 for email in variations[:max_variations]: iterations += 1 - pos.add( - instance.pick_color_bank_index(email, - instance.get_color_bank())) + pos.add(instance.pick_color_bank_index(email, instance.get_color_bank())) # we assume that we have match all 256 possible positions, # in reasonable amount of different email addresses @@ -419,36 +493,68 @@ def test_initials_gravatar_mapping_algo(): assert iterations == max_variations -@pytest.mark.parametrize("tmpl, repo_name, overrides, prefix, expected", [ - (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '', 'http://vps1:8000/group/repo1'), - (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/group/repo1'), - (Repository.DEFAULT_CLONE_URI, 'group/repo1', {}, '/rc', 'http://vps1:8000/rc/group/repo1'), - (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc', 'http://user@vps1:8000/rc/group/repo1'), - (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc', 'http://marcink@vps1:8000/rc/group/repo1'), - (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'user'}, '/rc/', 'http://user@vps1:8000/rc/group/repo1'), - (Repository.DEFAULT_CLONE_URI, 'group/repo1', {'user': 'marcink'}, '/rc/', 'http://marcink@vps1:8000/rc/group/repo1'), - ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {}, '', 'http://vps1:8000/_23'), - ('{scheme}://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'), - ('http://{user}@{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://marcink@vps1:8000/_23'), - ('http://{netloc}/_{repoid}', 'group/repo1', {'user': 'marcink'}, '', 'http://vps1:8000/_23'), - ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://marcink@proxy1.server.com/group/repo1'), - ('https://{user}@proxy1.server.com/{repo}', 'group/repo1', {}, '', 'https://proxy1.server.com/group/repo1'), - ('https://proxy1.server.com/{user}/{repo}', 'group/repo1', {'user': 'marcink'}, '', 'https://proxy1.server.com/marcink/group/repo1'), -]) +@pytest.mark.parametrize( + "tmpl, repo_name, overrides, prefix, expected", + [ + (Repository.DEFAULT_CLONE_URI, "group/repo1", {}, "", "http://vps1:8000/group/repo1"), + (Repository.DEFAULT_CLONE_URI, "group/repo1", {"user": "marcink"}, "", "http://marcink@vps1:8000/group/repo1"), + (Repository.DEFAULT_CLONE_URI, "group/repo1", {}, "/rc", "http://vps1:8000/rc/group/repo1"), + (Repository.DEFAULT_CLONE_URI, "group/repo1", {"user": "user"}, "/rc", "http://user@vps1:8000/rc/group/repo1"), + ( + Repository.DEFAULT_CLONE_URI, + "group/repo1", + {"user": "marcink"}, + "/rc", + "http://marcink@vps1:8000/rc/group/repo1", + ), + (Repository.DEFAULT_CLONE_URI, "group/repo1", {"user": "user"}, "/rc/", "http://user@vps1:8000/rc/group/repo1"), + ( + Repository.DEFAULT_CLONE_URI, + "group/repo1", + {"user": "marcink"}, + "/rc/", + "http://marcink@vps1:8000/rc/group/repo1", + ), + ("{scheme}://{user}@{netloc}/_{repoid}", "group/repo1", {}, "", "http://vps1:8000/_23"), + ( + "{scheme}://{user}@{netloc}/_{repoid}", + "group/repo1", + {"user": "marcink"}, + "", + "http://marcink@vps1:8000/_23", + ), + ("http://{user}@{netloc}/_{repoid}", "group/repo1", {"user": "marcink"}, "", "http://marcink@vps1:8000/_23"), + ("http://{netloc}/_{repoid}", "group/repo1", {"user": "marcink"}, "", "http://vps1:8000/_23"), + ( + "https://{user}@proxy1.server.com/{repo}", + "group/repo1", + {"user": "marcink"}, + "", + "https://marcink@proxy1.server.com/group/repo1", + ), + ("https://{user}@proxy1.server.com/{repo}", "group/repo1", {}, "", "https://proxy1.server.com/group/repo1"), + ( + "https://proxy1.server.com/{user}/{repo}", + "group/repo1", + {"user": "marcink"}, + "", + "https://proxy1.server.com/marcink/group/repo1", + ), + ], +) def test_clone_url_generator(tmpl, repo_name, overrides, prefix, expected): from rhodecode.lib.utils2 import get_clone_url class RequestStub(object): def request_url(self, name): - return 'http://vps1:8000' + prefix + return "http://vps1:8000" + prefix def route_url(self, name): return self.request_url(name) clone_url = get_clone_url( - request=RequestStub(), - uri_tmpl=tmpl, - repo_name=repo_name, repo_id=23, repo_type='hg', **overrides) + request=RequestStub(), uri_tmpl=tmpl, repo_name=repo_name, repo_id=23, repo_type="hg", **overrides + ) assert clone_url == expected @@ -457,7 +563,7 @@ def test_clone_url_svn_ssh_generator(): class RequestStub(object): def request_url(self, name): - return 'http://vps1:8000' + return "http://vps1:8000" def route_url(self, name): return self.request_url(name) @@ -465,22 +571,32 @@ def test_clone_url_svn_ssh_generator(): clone_url = get_clone_url( request=RequestStub(), uri_tmpl=Repository.DEFAULT_CLONE_URI_SSH, - repo_name='svn-test', repo_id=23, repo_type='svn', **{'sys_user': 'rcdev'}) - assert clone_url == 'svn+ssh://rcdev@vps1/svn-test' + repo_name="svn-test", + repo_id=23, + repo_type="svn", + **{"sys_user": "rcdev"}, + ) + assert clone_url == "svn+ssh://rcdev@vps1/svn-test" idx = 0 -def _quick_url(text, tmpl="""%s""", url_=None, commits=''): +def _quick_url( + text, + tmpl="""%s""", + url_=None, + commits="", +): """ Changes `some text url[foo]` => `some text foo :param text: """ import re + # quickly change expected url[] into a link - url_pat = re.compile(r'(?:url\[)(.+?)(?:\])') + url_pat = re.compile(r"(?:url\[)(.+?)(?:\])") commits = commits or [] global idx @@ -492,56 +608,37 @@ def _quick_url(text, tmpl="""%s""", url_=url_) assert urlify_text(sample) == expected -@pytest.mark.parametrize("test, expected", [ - ("", None), - ("/_2", '2'), - ("_2", '2'), - ("/_2/", '2'), - ("_2/", '2'), - - ("/_21", '21'), - ("_21", '21'), - ("/_21/", '21'), - ("_21/", '21'), - - ("/_21/foobar", '21'), - ("_21/121", '21'), - ("/_21/_12", '21'), - ("_21/rc/foo", '21'), - -]) +@pytest.mark.parametrize( + "test, expected", + [ + ("", None), + ("/_2", "2"), + ("_2", "2"), + ("/_2/", "2"), + ("_2/", "2"), + ("/_21", "21"), + ("_21", "21"), + ("/_21/", "21"), + ("_21/", "21"), + ("/_21/foobar", "21"), + ("_21/121", "21"), + ("/_21/_12", "21"), + ("_21/rc/foo", "21"), + ], +) def test_get_repo_by_id(test, expected): from rhodecode.model.repo import RepoModel + _test = RepoModel()._extract_id_from_repo_name(test) assert _test == expected @@ -620,18 +720,17 @@ def test_get_repo_by_id(test, expected): def test_invalidation_context(baseapp): repo_id = 9999 calls = [1, 2] - call_args = ('some-key',) - region = rc_cache.get_or_create_region('cache_repo_longterm') + call_args = ("some-key",) + region = rc_cache.get_or_create_region("cache_repo_longterm") repo_namespace_key = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=repo_id) inv_context_manager = rc_cache.InvalidationContext(key=repo_namespace_key) def cache_generator(_state_uid): - - @region.conditional_cache_on_arguments(namespace=f'some-common-namespace-{repo_id}') + @region.conditional_cache_on_arguments(namespace=f"some-common-namespace-{repo_id}") def _dummy_func(*args): val = calls.pop(0) - return _state_uid, f'result:{val}' + return _state_uid, f"result:{val}" return _dummy_func @@ -647,10 +746,10 @@ def test_invalidation_context(baseapp): assert should_invalidate is False # 1st call, we don't need to invalidate - assert 'result:1' == result + assert "result:1" == result # should be already cached so calling it twice will give the same result! _, result = cache_func(*call_args) - assert 'result:1' == result + assert "result:1" == result # 2nd call, we create a new context manager, this should be now key aware, and # return an active cache region from DB based on the same uid @@ -680,29 +779,28 @@ def test_invalidation_context(baseapp): assert should_invalidate is True - assert 'result:2' == result + assert "result:2" == result # cached again, same result _, result = cache_func(*call_args) - assert 'result:2' == result + assert "result:2" == result def test_invalidation_context_exception_in_compute(baseapp): repo_id = 888 - region = rc_cache.get_or_create_region('cache_repo_longterm') + region = rc_cache.get_or_create_region("cache_repo_longterm") repo_namespace_key = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=repo_id) inv_context_manager = rc_cache.InvalidationContext(key=repo_namespace_key) def cache_generator(_state_uid): - @region.conditional_cache_on_arguments(namespace=f'some-common-namespace-{repo_id}') + @region.conditional_cache_on_arguments(namespace=f"some-common-namespace-{repo_id}") def _dummy_func(*args): - raise Exception('Error in cache func') + raise Exception("Error in cache func") return _dummy_func with pytest.raises(Exception): - # 1st call, fresh caches with inv_context_manager as invalidation_context: cache_state_uid = invalidation_context.state_uid @@ -710,12 +808,11 @@ def test_invalidation_context_exception_in_compute(baseapp): cache_func(1, 2, 3) -@pytest.mark.parametrize('execution_number', range(5)) +@pytest.mark.parametrize("execution_number", range(5)) def test_cache_invalidation_race_condition(execution_number, baseapp): - repo_id = 777 - region = rc_cache.get_or_create_region('cache_repo_longterm') + region = rc_cache.get_or_create_region("cache_repo_longterm") repo_namespace_key = CacheKey.REPO_INVALIDATION_NAMESPACE.format(repo_id=repo_id) @run_test_concurrently(25) @@ -723,10 +820,9 @@ def test_cache_invalidation_race_condition(execution_number, baseapp): time.sleep(0.2) def cache_generator(_state_uid): - - @region.conditional_cache_on_arguments(namespace=f'some-common-namespace-{repo_id}') + @region.conditional_cache_on_arguments(namespace=f"some-common-namespace-{repo_id}") def _dummy_func(*args): - return _state_uid, 'result:async' + return _state_uid, "result:async" return _dummy_func @@ -736,11 +832,11 @@ def test_cache_invalidation_race_condition(execution_number, baseapp): with inv_context_manager as invalidation_context: cache_state_uid = invalidation_context.state_uid cache_func = cache_generator(cache_state_uid) - previous_state_uid, result = cache_func('doo') + previous_state_uid, result = cache_func("doo") should_invalidate = previous_state_uid != cache_state_uid if should_invalidate: - _, result = cache_func.refresh('doo') + _, result = cache_func.refresh("doo") # Mark invalidation CacheKey.set_invalidate(repo_namespace_key) diff --git a/rhodecode/tests/lib/test_mako_emails.py b/rhodecode/tests/lib/test_mako_emails.py index ead333c3..b483c828 100644 --- a/rhodecode/tests/lib/test_mako_emails.py +++ b/rhodecode/tests/lib/test_mako_emails.py @@ -29,167 +29,153 @@ from rhodecode.model.notification import EmailNotificationModel def pr(): def factory(ref): return collections.namedtuple( - 'PullRequest', - 'pull_request_id, title, title_safe, description, source_ref_parts, source_ref_name, target_ref_parts, target_ref_name')\ - (200, 'Example Pull Request', 'Example Pull Request', 'Desc of PR', ref, 'bookmark', ref, 'Branch') + "PullRequest", + "pull_request_id, title, title_safe, description, source_ref_parts, source_ref_name, target_ref_parts, target_ref_name", + )(200, "Example Pull Request", "Example Pull Request", "Desc of PR", ref, "bookmark", ref, "Branch") + return factory def test_get_template_obj(app, request_stub): - template = EmailNotificationModel().get_renderer( - EmailNotificationModel.TYPE_TEST, request_stub) + template = EmailNotificationModel().get_renderer(EmailNotificationModel.TYPE_TEST, request_stub) assert isinstance(template, PyramidPartialRenderer) def test_render_email(app, http_host_only_stub): kwargs = {} - subject, body, body_plaintext = EmailNotificationModel().render_email( - EmailNotificationModel.TYPE_TEST, **kwargs) + subject, body, body_plaintext = EmailNotificationModel().render_email(EmailNotificationModel.TYPE_TEST, **kwargs) # subject assert subject == 'Test "Subject" hello "world"' # body plaintext - assert body_plaintext == 'Email Plaintext Body' + assert body_plaintext == "Email Plaintext Body" # body - notification_footer1 = 'This is a notification from RhodeCode.' - notification_footer2 = 'http://{}/'.format(http_host_only_stub) + notification_footer1 = "This is a notification from RhodeCode." + notification_footer2 = "http://{}/".format(http_host_only_stub) assert notification_footer1 in body assert notification_footer2 in body - assert 'Email Body' in body + assert "Email Body" in body -@pytest.mark.parametrize('role', PullRequestReviewers.ROLES) +@pytest.mark.parametrize("role", PullRequestReviewers.ROLES) def test_render_pr_email(app, user_admin, role, pr): - ref = collections.namedtuple( - 'Ref', 'name, type')('fxies123', 'book') + ref = collections.namedtuple("Ref", "name, type")("fxies123", "book") pr = pr(ref) - source_repo = target_repo = collections.namedtuple( - 'Repo', 'type, repo_name')('hg', 'pull_request_1') + source_repo = target_repo = collections.namedtuple("Repo", "type, repo_name")("hg", "pull_request_1") kwargs = { - 'user': User.get_first_super_admin(), - 'pull_request': pr, - 'pull_request_commits': [], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'x', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'x', - - 'pull_request_url': 'http://localhost/pr1', - 'user_role': role, + "user": User.get_first_super_admin(), + "pull_request": pr, + "pull_request_commits": [], + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "x", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "x", + "pull_request_url": "http://localhost/pr1", + "user_role": role, } subject, body, body_plaintext = EmailNotificationModel().render_email( - EmailNotificationModel.TYPE_PULL_REQUEST, **kwargs) + EmailNotificationModel.TYPE_PULL_REQUEST, **kwargs + ) # subject if role == PullRequestReviewers.ROLE_REVIEWER: assert subject == '@test_admin (RhodeCode Admin) requested a pull request review. !200: "Example Pull Request"' elif role == PullRequestReviewers.ROLE_OBSERVER: - assert subject == '@test_admin (RhodeCode Admin) added you as observer to pull request. !200: "Example Pull Request"' + assert ( + subject + == '@test_admin (RhodeCode Admin) added you as observer to pull request. !200: "Example Pull Request"' + ) def test_render_pr_update_email(app, user_admin, pr): - ref = collections.namedtuple( - 'Ref', 'name, type')('fxies123', 'book') + ref = collections.namedtuple("Ref", "name, type")("fxies123", "book") pr = pr(ref) - source_repo = target_repo = collections.namedtuple( - 'Repo', 'type, repo_name')('hg', 'pull_request_1') + source_repo = target_repo = collections.namedtuple("Repo", "type, repo_name")("hg", "pull_request_1") - commit_changes = AttributeDict({ - 'added': ['aaaaaaabbbbb', 'cccccccddddddd'], - 'removed': ['eeeeeeeeeee'], - }) - file_changes = AttributeDict({ - 'added': ['a/file1.md', 'file2.py'], - 'modified': ['b/modified_file.rst'], - 'removed': ['.idea'], - }) + commit_changes = AttributeDict( + { + "added": ["aaaaaaabbbbb", "cccccccddddddd"], + "removed": ["eeeeeeeeeee"], + } + ) + file_changes = AttributeDict( + { + "added": ["a/file1.md", "file2.py"], + "modified": ["b/modified_file.rst"], + "removed": [".idea"], + } + ) kwargs = { - 'updating_user': User.get_first_super_admin(), - - 'pull_request': pr, - 'pull_request_commits': [], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'x', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'x', - - 'pull_request_url': 'http://localhost/pr1', - - 'pr_comment_url': 'http://comment-url', - 'pr_comment_reply_url': 'http://comment-url#reply', - 'ancestor_commit_id': 'f39bd443', - 'added_commits': commit_changes.added, - 'removed_commits': commit_changes.removed, - 'changed_files': (file_changes.added + file_changes.modified + file_changes.removed), - 'added_files': file_changes.added, - 'modified_files': file_changes.modified, - 'removed_files': file_changes.removed, + "updating_user": User.get_first_super_admin(), + "pull_request": pr, + "pull_request_commits": [], + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "x", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "x", + "pull_request_url": "http://localhost/pr1", + "pr_comment_url": "http://comment-url", + "pr_comment_reply_url": "http://comment-url#reply", + "ancestor_commit_id": "f39bd443", + "added_commits": commit_changes.added, + "removed_commits": commit_changes.removed, + "changed_files": (file_changes.added + file_changes.modified + file_changes.removed), + "added_files": file_changes.added, + "modified_files": file_changes.modified, + "removed_files": file_changes.removed, } subject, body, body_plaintext = EmailNotificationModel().render_email( - EmailNotificationModel.TYPE_PULL_REQUEST_UPDATE, **kwargs) + EmailNotificationModel.TYPE_PULL_REQUEST_UPDATE, **kwargs + ) # subject assert subject == '@test_admin (RhodeCode Admin) updated pull request. !200: "Example Pull Request"' -@pytest.mark.parametrize('mention', [ - True, - False -]) -@pytest.mark.parametrize('email_type', [ - EmailNotificationModel.TYPE_COMMIT_COMMENT, - EmailNotificationModel.TYPE_PULL_REQUEST_COMMENT -]) +@pytest.mark.parametrize("mention", [True, False]) +@pytest.mark.parametrize( + "email_type", [EmailNotificationModel.TYPE_COMMIT_COMMENT, EmailNotificationModel.TYPE_PULL_REQUEST_COMMENT] +) def test_render_comment_subject_no_newlines(app, mention, email_type, pr): - ref = collections.namedtuple( - 'Ref', 'name, type')('fxies123', 'book') + ref = collections.namedtuple("Ref", "name, type")("fxies123", "book") pr = pr(ref) - source_repo = target_repo = collections.namedtuple( - 'Repo', 'type, repo_name')('hg', 'pull_request_1') + source_repo = target_repo = collections.namedtuple("Repo", "type, repo_name")("hg", "pull_request_1") kwargs = { - 'user': User.get_first_super_admin(), - 'commit': AttributeDict(raw_id='a'*40, message='Commit message'), - 'status_change': 'approved', - 'commit_target_repo_url': 'http://foo.example.com/#comment1', - 'repo_name': 'test-repo', - 'comment_file': 'test-file.py', - 'comment_line': 'n100', - 'comment_type': 'note', - 'comment_id': 2048, - 'commit_comment_url': 'http://comment-url', - 'commit_comment_reply_url': 'http://comment-url/#Reply', - 'instance_url': 'http://rc-instance', - 'comment_body': 'hello world', - 'mention': mention, - - 'pr_comment_url': 'http://comment-url', - 'pr_comment_reply_url': 'http://comment-url/#Reply', - 'pull_request': pr, - 'pull_request_commits': [], - - 'pull_request_target_repo': target_repo, - 'pull_request_target_repo_url': 'x', - - 'pull_request_source_repo': source_repo, - 'pull_request_source_repo_url': 'x', - - 'pull_request_url': 'http://code.rc.com/_pr/123' + "user": User.get_first_super_admin(), + "commit": AttributeDict(raw_id="a" * 40, message="Commit message"), + "status_change": "approved", + "commit_target_repo_url": "http://foo.example.com/#comment1", + "repo_name": "test-repo", + "comment_file": "test-file.py", + "comment_line": "n100", + "comment_type": "note", + "comment_id": 2048, + "commit_comment_url": "http://comment-url", + "commit_comment_reply_url": "http://comment-url/#Reply", + "instance_url": "http://rc-instance", + "comment_body": "hello world", + "mention": mention, + "pr_comment_url": "http://comment-url", + "pr_comment_reply_url": "http://comment-url/#Reply", + "pull_request": pr, + "pull_request_commits": [], + "pull_request_target_repo": target_repo, + "pull_request_target_repo_url": "x", + "pull_request_source_repo": source_repo, + "pull_request_source_repo_url": "x", + "pull_request_url": "http://code.rc.com/_pr/123", } subject, body, body_plaintext = EmailNotificationModel().render_email(email_type, **kwargs) - assert '\n' not in subject + assert "\n" not in subject diff --git a/rhodecode/tests/lib/test_markup_renderer.py b/rhodecode/tests/lib/test_markup_renderer.py index 7230dadb..0a826ba4 100644 --- a/rhodecode/tests/lib/test_markup_renderer.py +++ b/rhodecode/tests/lib/test_markup_renderer.py @@ -19,54 +19,48 @@ import mock import pytest -from rhodecode.lib.markup_renderer import ( - MarkupRenderer, RstTemplateRenderer, relative_path, relative_links) +from rhodecode.lib.markup_renderer import MarkupRenderer, RstTemplateRenderer, relative_path, relative_links @pytest.mark.parametrize( "filename, expected_renderer", [ - ('readme.md', 'markdown'), - ('readme.Md', 'markdown'), - ('readme.MdoWn', 'markdown'), - ('readme.rst', 'rst'), - ('readme.Rst', 'rst'), - ('readme.rest', 'rst'), - ('readme.rest', 'rst'), - - ('markdown.xml', 'plain'), - ('rest.xml', 'plain'), - ('readme.xml', 'plain'), - - ('readme', 'plain'), - ('README', 'plain'), - ('readme.mdx', 'plain'), - ('readme.rstx', 'plain'), - ('readmex', 'plain'), - ]) + ("readme.md", "markdown"), + ("readme.Md", "markdown"), + ("readme.MdoWn", "markdown"), + ("readme.rst", "rst"), + ("readme.Rst", "rst"), + ("readme.rest", "rst"), + ("readme.rest", "rst"), + ("markdown.xml", "plain"), + ("rest.xml", "plain"), + ("readme.xml", "plain"), + ("readme", "plain"), + ("README", "plain"), + ("readme.mdx", "plain"), + ("readme.rstx", "plain"), + ("readmex", "plain"), + ], +) def test_detect_renderer(filename, expected_renderer): - detected_renderer = MarkupRenderer()._detect_renderer( - '', filename=filename).__name__ + detected_renderer = MarkupRenderer()._detect_renderer("", filename=filename).__name__ assert expected_renderer == detected_renderer def test_markdown_xss_link(): xss_md = "[link](javascript:alert('XSS: pwned!'))" rendered_html = MarkupRenderer.markdown(xss_md) - assert 'href="javascript:alert(\'XSS: pwned!\')"' not in rendered_html + assert "href=\"javascript:alert('XSS: pwned!')\"" not in rendered_html def test_markdown_xss_inline_html(): - xss_md = '\n'.join([ - '> href="javascript:alert(\'XSS: pwned!\')">link']) + xss_md = "\n".join(['> href=\"javascript:alert('XSS: pwned!')\">link"]) rendered_html = MarkupRenderer.markdown(xss_md) - assert 'href="javascript:alert(\'XSS: pwned!\')">' not in rendered_html + assert "href=\"javascript:alert('XSS: pwned!')\">" not in rendered_html def test_markdown_inline_html(): - xss_md = '\n'.join(['> onload="javascript:alert()" href="https://rhodecode.com">link']) + xss_md = "\n".join(['> onload="javascript:alert()" href="https://rhodecode.com">link']) rendered_html = MarkupRenderer.markdown(xss_md) assert 'link' in rendered_html @@ -503,24 +497,21 @@ def test_rst_xss_link(): assert "href=javascript:alert('XSS: pwned!')" not in rendered_html -@pytest.mark.xfail(reason='Bug in docutils. Waiting answer from the author') +@pytest.mark.xfail(reason="Bug in docutils. Waiting answer from the author") def test_rst_xss_inline_html(): - xss_rst = 'link' + xss_rst = "link" rendered_html = MarkupRenderer.rst(xss_rst) assert 'href="javascript:alert(' not in rendered_html def test_rst_xss_raw_directive(): - xss_rst = '\n'.join([ - '.. raw:: html', - '', - ' link']) + xss_rst = "\n".join([".. raw:: html", "", " link"]) rendered_html = MarkupRenderer.rst(xss_rst) assert 'href="javascript:alert(' not in rendered_html def test_render_rst_template_without_files(): - expected = u'''\ + expected = """\ Pull request updated. Auto status change to |under_review| .. role:: added @@ -533,25 +524,25 @@ Pull request updated. Auto status change to |under_review| No file changes found -.. |under_review| replace:: *"NEW STATUS"*''' +.. |under_review| replace:: *"NEW STATUS"*""" params = { - 'under_review_label': 'NEW STATUS', - 'added_commits': ['a', 'b'], - 'removed_commits': ['a', 'b', 'c'], - 'changed_files': [], - 'added_files': [], - 'modified_files': [], - 'removed_files': [], - 'ancestor_commit_id': 'aaabbbcccdddeee', + "under_review_label": "NEW STATUS", + "added_commits": ["a", "b"], + "removed_commits": ["a", "b", "c"], + "changed_files": [], + "added_files": [], + "modified_files": [], + "removed_files": [], + "ancestor_commit_id": "aaabbbcccdddeee", } renderer = RstTemplateRenderer() - rendered = renderer.render('pull_request_update.mako', **params) + rendered = renderer.render("pull_request_update.mako", **params) assert expected == rendered def test_render_rst_template_with_files(): - expected = u'''\ + expected = """\ Pull request updated. Auto status change to |under_review| .. role:: added @@ -569,98 +560,66 @@ Pull request updated. Auto status change to |under_review| * `M /path/ę.py <#a_c-aaabbbcccddd-d713adf009cd>`_ * `R /path/ź.py` -.. |under_review| replace:: *"NEW STATUS"*''' +.. |under_review| replace:: *"NEW STATUS"*""" - added = ['/path/a.py', '/path/b.js'] - modified = ['/path/d.js', u'/path/ę.py'] - removed = [u'/path/ź.py'] + added = ["/path/a.py", "/path/b.js"] + modified = ["/path/d.js", "/path/ę.py"] + removed = ["/path/ź.py"] params = { - 'under_review_label': 'NEW STATUS', - 'added_commits': ['a'], - 'removed_commits': ['a', 'b', 'c'], - 'changed_files': added + modified + removed, - 'added_files': added, - 'modified_files': modified, - 'removed_files': removed, - 'ancestor_commit_id': 'aaabbbcccdddeee', + "under_review_label": "NEW STATUS", + "added_commits": ["a"], + "removed_commits": ["a", "b", "c"], + "changed_files": added + modified + removed, + "added_files": added, + "modified_files": modified, + "removed_files": removed, + "ancestor_commit_id": "aaabbbcccdddeee", } renderer = RstTemplateRenderer() - rendered = renderer.render('pull_request_update.mako', **params) + rendered = renderer.render("pull_request_update.mako", **params) assert expected == rendered def test_render_rst_auto_status_template(): - expected = u'''\ + expected = """\ Auto status change to |new_status| -.. |new_status| replace:: *"NEW STATUS"*''' +.. |new_status| replace:: *"NEW STATUS"*""" params = { - 'new_status_label': 'NEW STATUS', - 'pull_request': None, - 'commit_id': None, + "new_status_label": "NEW STATUS", + "pull_request": None, + "commit_id": None, } renderer = RstTemplateRenderer() - rendered = renderer.render('auto_status_change.mako', **params) + rendered = renderer.render("auto_status_change.mako", **params) assert expected == rendered @pytest.mark.parametrize( "src_path, server_path, is_path, expected", [ - ('source.png', '/repo/files/path', lambda p: False, - '/repo/files/path/source.png'), - - ('source.png', 'mk/git/blob/master/README.md', lambda p: True, - '/mk/git/blob/master/source.png'), - - ('./source.png', 'mk/git/blob/master/README.md', lambda p: True, - '/mk/git/blob/master/source.png'), - - ('/source.png', 'mk/git/blob/master/README.md', lambda p: True, - '/mk/git/blob/master/source.png'), - - ('./source.png', 'repo/files/path/source.md', lambda p: True, - '/repo/files/path/source.png'), - - ('./source.png', '/repo/files/path/file.md', lambda p: True, - '/repo/files/path/source.png'), - - ('../source.png', '/repo/files/path/file.md', lambda p: True, - '/repo/files/source.png'), - - ('./../source.png', '/repo/files/path/file.md', lambda p: True, - '/repo/files/source.png'), - - ('./source.png', '/repo/files/path/file.md', lambda p: True, - '/repo/files/path/source.png'), - - ('../../../source.png', 'path/file.md', lambda p: True, - '/source.png'), - - ('../../../../../source.png', '/path/file.md', None, - '/source.png'), - - ('../../../../../source.png', 'files/path/file.md', None, - '/source.png'), - - ('../../../../../https://google.com/image.png', 'files/path/file.md', None, - '/https://google.com/image.png'), - - ('https://google.com/image.png', 'files/path/file.md', None, - 'https://google.com/image.png'), - - ('://foo', '/files/path/file.md', None, - '://foo'), - - (u'한글.png', '/files/path/file.md', None, - u'/files/path/한글.png'), - - ('my custom image.png', '/files/path/file.md', None, - '/files/path/my custom image.png'), - ]) + ("source.png", "/repo/files/path", lambda p: False, "/repo/files/path/source.png"), + ("source.png", "mk/git/blob/master/README.md", lambda p: True, "/mk/git/blob/master/source.png"), + ("./source.png", "mk/git/blob/master/README.md", lambda p: True, "/mk/git/blob/master/source.png"), + ("/source.png", "mk/git/blob/master/README.md", lambda p: True, "/mk/git/blob/master/source.png"), + ("./source.png", "repo/files/path/source.md", lambda p: True, "/repo/files/path/source.png"), + ("./source.png", "/repo/files/path/file.md", lambda p: True, "/repo/files/path/source.png"), + ("../source.png", "/repo/files/path/file.md", lambda p: True, "/repo/files/source.png"), + ("./../source.png", "/repo/files/path/file.md", lambda p: True, "/repo/files/source.png"), + ("./source.png", "/repo/files/path/file.md", lambda p: True, "/repo/files/path/source.png"), + ("../../../source.png", "path/file.md", lambda p: True, "/source.png"), + ("../../../../../source.png", "/path/file.md", None, "/source.png"), + ("../../../../../source.png", "files/path/file.md", None, "/source.png"), + ("../../../../../https://google.com/image.png", "files/path/file.md", None, "/https://google.com/image.png"), + ("https://google.com/image.png", "files/path/file.md", None, "https://google.com/image.png"), + ("://foo", "/files/path/file.md", None, "://foo"), + ("한글.png", "/files/path/file.md", None, "/files/path/한글.png"), + ("my custom image.png", "/files/path/file.md", None, "/files/path/my custom image.png"), + ], +) def test_relative_path(src_path, server_path, is_path, expected): path = relative_path(src_path, server_path, is_path) assert path == expected @@ -669,7 +628,7 @@ def test_relative_path(src_path, server_path, is_path, expected): @pytest.mark.parametrize( "src_html, expected_html", [ - ('
', '
'), + ("
", "
"), ('', ''), ('', ''), ('', ''), @@ -678,15 +637,18 @@ def test_relative_path(src_path, server_path, is_path, expected): ('', ''), ('', ''), ('', ''), - - ]) + ], +) def test_relative_links(src_html, expected_html): - server_paths = {'raw': '/path/raw/file.md', 'standard': '/path/file.md'} + server_paths = {"raw": "/path/raw/file.md", "standard": "/path/file.md"} assert relative_links(src_html, server_paths=server_paths) == expected_html -@pytest.mark.parametrize("notebook_source, expected_output", [ - (""" +@pytest.mark.parametrize( + "notebook_source, expected_output", + [ + ( + """ { "nbformat": 3, "nbformat_minor": 0, @@ -731,8 +693,11 @@ def test_relative_links(src_html, expected_html): } } } - """, "Hello, World!"), - (""" + """, + "Hello, World!", + ), + ( + """ { "nbformat": 4, "nbformat_minor": 1, @@ -775,122 +740,112 @@ def test_relative_links(src_html, expected_html): } } } - """, "Hello, World!") -]) + """, + "Hello, World!", + ), + ], +) def test_jp_notebook_html_generation(notebook_source, expected_output): - with mock.patch('rhodecode.lib.helpers.asset'): + with mock.patch("rhodecode.lib.helpers.asset"): body = MarkupRenderer.jupyter(notebook_source) assert "" in body assert expected_output in body -@pytest.mark.parametrize("notebook_source, expected_output", [ - ({"cells": [ - { - "cell_type": "code", - "execution_count": 0, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n" +@pytest.mark.parametrize( + "notebook_source, expected_output", + [ + ( + { + "cells": [ + { + "cell_type": "code", + "execution_count": 0, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": ["\n"], + "text/plain": [], + }, + "metadata": {}, + "output_type": "display_data", + } ], - "text/plain": [] + "source": [""], + } + ], + "metadata": { + "kernelspec": {"display_name": "Python 3", "language": "python", "name": "python3"}, + "language_info": { + "codemirror_mode": {"name": "ipython", "version": 3}, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.6", }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "" - ] - } + }, + "nbformat": 4, + "nbformat_minor": 5, + }, + 'No description has been provided for this image', + ), + ( + { + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": ['\n'], + }, + { + "cell_type": "markdown", + "metadata": {"highlighter": "codemirror"}, + "source": '', + }, + { + "cell_type": "code", + "execution_count": 0, + "metadata": {"xrender": True}, + "outputs": [ + { + "data": { + "text/html": [ + "